J'ai un problème pour lancer un objet sur l'une des interfaces de base d'une autre bibliothèque. Voici le code correspondant:Transférer un objet à l'interface de base
BaseSDK.dll
public interface IPlugin
{
void Run();
}
CustomPlugin.Definition.dll:
public interface ICustomPlugin
{
void DoCustomStuff();
}
CustomPlugin.dll (a référence à BaseSDK.dll et CustomPlugin.Definition.dll):
public class CustomPlugin: IPlugin, ICustomPlugin
{
public void Run()
{
}
public void DoCustomStuff()
{
}
}
host.exe (a des références à BaseSDK.dll et 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();
}
Je ne comprends pas; c'est juste type-cast un type à son type de base. Comment puis-je réparer cela? ou des alternatives?
Edit: Voici un résumé de ce LoadPluginAndCreateAnInstanceSomehow()
fait:
Assembly ass = Assembly.LoadFrom(filename);
Type t = ass.GetType(ass.FullName + ".CustomPlugin");
plugin = (IPlugin)Activator.CreateInstance(t);
Edit 2: Plugins sont chargés dans un autre AppDomain. J'ai dû ajouter IPlugin et ICustomPlugin.Definiton comme référence à la compilation car l'application doit avoir une idée de ce qu'est un CustomPlugin. Est-ce la source du problème? si oui, comment puis-je réaliser ce que j'essaie de faire?
Edit 3: Plugins sont chargés comme ceci:
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);
}
}
}
Pouvez-vous nous montrer comment vous chargez le plug-in dans un autre AppDomain? J'ai essayé ceci avec la DLL dans différents endroits, mais je ne peux pas reproduire votre problème. – Sam
Assemblage ass = Assembly.LoadFrom (fi.FullName). lol au nom de la variable. – obelix
Je suis confus. Pourquoi s'attend-on à ce que les types chargés à partir d'un autre domaine d'application soient compatibles avec les mêmes types chargés dans le domaine d'application actuel? –