Hello, I have got a problem on casting an object to one of it's base interfaces living in another library. Here is the code for it:
BaseSDK.dll
public interface IPlugin
{
void Run();
}
CustomPlugin.Definition.dll:
public interface ICustomPlugin
{
void DoCustomStuff();
}
CustomPlugin.dll (has reference to BaseSDK.dll and CustomPlugin.Definition.dll):
public class CustomPlugin: IPlugin, ICustomPlugin
{
public void Run()
{
}
public void DoCustomStuff()
{
}
}
Host.exe (has references to BaseSDK.dll and CustomPlugin.Definition.dll):
IPlugin plugin;
public void DoStuff()
{
plugin = LoadPluginAndCreateAnInstanceSomehow();
// I know plugin is a CustomPlugin
ICustomPlugin customPlugin = plugin as ICustomPlugin; //cast fails.
customPlugin.DoCustomStuff();
}
I don't understand; this is just plain type-casting a type to it's base type. How can i fix this? or any alternatives?
Edit: Here is a summary of what LoadPluginAndCreateAnInstanceSomehow()
does:
Assembly ass = Assembly.LoadFrom(filename);
Type t = ass.GetType(ass.FullName + ".CustomPlugin");
plugin = (IPlugin)Activator.CreateInstance(t);
Edit 2: Plugins are loaded into another AppDomain. I had to add IPlugin and ICustomPlugin.Definiton as reference at compile-time because the app must have a clue about what an CustomPlugin is like. is this the source of the problem? if so, how can I achieve what I'm trying to do?
Edit 3: Plugins are loaded like this:
public class PluginLoader
{
List<IPlugin> Plugins;
AppDomain Domain;
string libPath;
public void PluginLoader(string sLibPath, AppDomain sDomain)
{
libPath = sLibPath;
Plugins = new List<IPlugin>();
Domain = sDomain;
if(Domain==null)Domain = AppDomain.CreateDomain("PluginsDomain");
Domain.AssemblyResolve += new ResolveEventHandler(Domain_AssemblyResolve);
Domain.TypeResolve += new ResolveEventHandler(Domain_TypeResolve);
Domain.DoCallBack(new CrossAppDomainDelegate(DomainCallback));
}
Assembly Domain_AssemblyResolve(object sender, ResolveEventArgs args)
{
return Assembly.LoadFrom(args.Name);
}
Assembly Domain_TypeResolve(object sender, ResolveEventArgs args)
{
return Assembly.LoadFrom(args.Name);
}
void DomainCallback()
{
string[] fileNames = Directory.GetFiles(libPath, "*.dll");
foreach (string filename in fileNames)
{
FileInfo fi = new FileInfo(filename);
Assembly ass = Assembly.LoadFrom(fi.FullName);
Type t = ass.GetType(ass.FullName + ".CustomPlugin");
IPlugin p = (IPlugin)Activator.CreateInstance(t);
Plugins.Add(p);
}
}
}