C# 将DLL加载到单独的AppDomain
我正在写一个插件架构。我的插件DLL位于运行插件管理器的子目录中。 我正在将插件加载到单独的AppDomain中,如下所示:C# 将DLL加载到单独的AppDomain,c#,.net,asp.net,assemblies,appdomain,C#,.net,Asp.net,Assemblies,Appdomain,我正在写一个插件架构。我的插件DLL位于运行插件管理器的子目录中。 我正在将插件加载到单独的AppDomain中,如下所示: string subDir;//initialized to the path of the module's directory. AppDomainSetup setup = new AppDomainSetup(); setup.PrivateBinPath = subDir; setup.ApplicationBase = subDir; AppDomain n
string subDir;//initialized to the path of the module's directory.
AppDomainSetup setup = new AppDomainSetup();
setup.PrivateBinPath = subDir;
setup.ApplicationBase = subDir;
AppDomain newDomain= AppDomain.CreateDomain(subDir, null, setup);
byte[] file = File.ReadAllBytes(dllPath);//dll path is a dll inside subDir
newDomain.Load(file);
不过。Load返回当前域尝试加载的程序集。因为插件DLL位于子目录中,所以当前域不能也不应该看到这些DLL,并且当前域引发FileLoadException
“ex={”无法加载文件或程序集…或其依赖项之一
问题是,我们可以将程序集加载到单独的AppDomain中,而不返回加载的程序集吗
我知道我可以为当前域中的AssemblyResolve事件添加一个处理程序并返回null,但我不想这样做
提前感谢。如下链接所示: 在另一个
AppDomain
对象上调用Load()
方法似乎也会导致在当前AppDomain
中加载该程序集
解决方案是使用
CreateInstanceFromAndUnwrap()AppDomain类的方法。您可以传递一个指向程序集的路径和要转换为的类型。您也可以使用DoCallBack-这是我在阅读了大量关于它的内容后整理的内容。这将创建一个AppDomain,检查程序集是否具有相同的签名公钥,加载程序集,执行静态me方法,卸载appdomain,然后删除dll
static void Main(string[] args)
{
string unknownAppPath = @"path-to-your-dll";
Console.WriteLine("Testing");
try
{
AppDomainSetup setup = new AppDomainSetup();
setup.AppDomainInitializer = new AppDomainInitializer(TestAppDomain);
setup.AppDomainInitializerArguments = new string[] { unknownAppPath };
AppDomain testDomain = AppDomain.CreateDomain("test", AppDomain.CurrentDomain.Evidence, setup);
AppDomain.Unload(testDomain);
File.Delete(unknownAppPath);
}
catch (Exception x)
{
Console.WriteLine(x.Message);
}
Console.ReadKey();
}
public static void TestAppDomain(string[] args)
{
string unknownAppPath = args[0];
AppDomain.CurrentDomain.DoCallBack(delegate()
{
//check that the new assembly is signed with the same public key
Assembly unknownAsm = AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(unknownAppPath));
//get the new assembly public key
byte[] unknownKeyBytes = unknownAsm.GetName().GetPublicKey();
string unknownKeyStr = BitConverter.ToString(unknownKeyBytes);
//get the current public key
Assembly asm = Assembly.GetExecutingAssembly();
AssemblyName aname = asm.GetName();
byte[] pubKey = aname.GetPublicKey();
string hexKeyStr = BitConverter.ToString(pubKey);
if (hexKeyStr == unknownKeyStr)
{
//keys match so execute a method
Type classType = unknownAsm.GetType("namespace.classname");
classType.InvokeMember("method-you-want-to-invoke", BindingFlags.InvokeMethod, null, null, null);
}
});
}
看看这个:还有这个:如果你正在构建一个插件架构,那么这篇文章可能会很有用: