将DLL加载到单独的AppDomain中

Ani*_*ish 4 .net c# 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 newDomain= AppDomain.CreateDomain(subDir, null, setup);

byte[] file = File.ReadAllBytes(dllPath);//dll path is a dll inside subDir
newDomain.Load(file);
Run Code Online (Sandbox Code Playgroud)

然而.newDomain.Load返回当前域尝试加载的程序集.因为插件dll位于子目录中,所以当前域不能也不应该看到这些dll,并且当前域抛出FileLoadException"ex = {"无法加载文件或程序集......或其依赖项之一.

问题是,我们可以将程序集加载到单独的AppDomain中而不返回已加载的程序集吗?

我知道我可以在当前域中为AssemblyResolve事件添加一个处理程序并返回null,但我宁愿不去这条路线.

提前致谢.

Aer*_*rik 5

你也可以使用DoCallBack - 这是我在SO上阅读了很多关于它的东西.这将创建一个appdomain,检查程序集是否具有相同的签名公钥,加载程序集,执行静态方法,卸载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);
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)


dec*_*one 2

正如下面给出的链接所指出的:

在不同的AppDomain中加载/卸载程序集

在新 AppDomain 中加载程序集,而不将其加载到父 AppDomain 中

似乎Load()在另一个AppDomain对象上调用方法会导致该程序集也加载到当前对象中AppDomain

解决方案是使用类CreateInstanceFromAndUnwrap()的方法。AppDomain您传递程序集的路径和要转换为的类型。