我需要在另一个域中加载 .dll(plugins)。在主应用程序中,我对插件类型一无所知,只知道它们使用一些方法实现了公共接口 ICommonInterface。所以这段代码无济于事,因为我无法创建具有接口类型的实例。
AppDomain domain = AppDomain.CreateDomain("New domain name");
//Do other things to the domain like set the security policy
string pathToDll = @"C:\myDll.dll"; //Full path to dll you want to load
Type t = typeof(TypeIWantToLoad);
TypeIWantToLoad myObject = (TypeIWantToLoad)domain.CreateInstanceFromAndUnwrap(pathToDll, t.FullName);
我的问题是如何在新域中加载程序集并获取实例,如果我只知道实现我想要创建的类型的接口名称。
更新:这是我的代码:MainLib.dll
namespace MainLib
{
public interface ICommonInterface
{
void ShowDllName();
}
}
PluginWithOutException.dll
namespace PluginWithOutException
{
public class WithOutException : MarshalByRefObject, ICommonInterface
{
public void ShowDllName()
{
Console.WriteLine("PluginWithOutException");
}
}
}
PluginWithException.dll
namespace PluginWithException
{
public class WithException : MarshalByRefObject, ICommonInterface
{
public void ShowDllName()
{
Console.WriteLine("WithException");
throw new NotImplementedException();
}
}
}
主要应用:
static void Main(string[] args)
{
string path = @"E:\Plugins\";
string[] assemblies = Directory.GetFiles(path);
List<string> plugins = SearchPlugins(assemblies);
foreach (string item in plugins)
{
CreateDomainAndLoadAssebly(item);
}
Console.ReadKey();
}
public static List<string> SearchPlugins(string[] names)
{
AppDomain domain = AppDomain.CreateDomain("tmpDomain");
domain.Load(Assembly.LoadFrom(@"E:\Plugins\MainLib.dll").FullName);
List<string> plugins = new List<string>();
foreach (string asm in names)
{
Assembly loadedAssembly = domain.Load(Assembly.LoadFrom(asm).FullName);
var theClassTypes = from t in loadedAssembly.GetTypes()
where t.IsClass &&
(t.GetInterface("ICommonInterface") != null)
select t;
if (theClassTypes.Count() > 0)
{
plugins.Add(asm);
}
}
AppDomain.Unload(domain);
return plugins;
}
插件和主应用程序引用了 MainLib.dll。主要目的是不在默认域中加载程序集,而是将它们加载到另一个域,所以当我不需要它们时,我只需 Unload() 域并从应用程序中卸载所有插件。
现在例外是FileNotFoundException, Could not load file or assembly 'PluginWithException, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.)
字符串Assembly loadedAssembly = domain.Load(Assembly.LoadFrom(asm).FullName);
(我试图加载名为 PluginWithException 的插件),我已经删除了插件中的所有依赖项,例如 System,我在这个域中加载了 System.dll(它加载正确并且它在域中),但仍然无法将插件加载到域中。我还检查了,PluginWithException 有 2 个依赖项——mscorlib 和 MainLib,它们都加载到了这个域。
更新:在这里我问了这个问题更多的细节。