Load Assembly into a new app domain but not CurrentDomain

天大地大妈咪最大 提交于 2019-12-11 04:08:07

问题


So my problem revolves around saving memory.

In essence I need to load an assembly in to a separate app domain other than the main/current domain, check for types within that assembly, and then unload the new domain when done.

Currently my solution is as follows:

AppDomain NewDomain = AppDomain.CreateDomain("newdomain");

foreach(string path in dllPaths) //string list of dll paths
{
    byte[] dllBytes = File.ReadAllBytes(dll);
    NewDomain.Load(dllBytes); //offending line
}

DoStuffWithNewDomain();
AppDomain.Unload(NewDomain);

The NewDomain.Load line seems to load the assembly into the new domain but also into the current domain of my program.

I used this link as a reference - http://www.csharp411.com/how-to-load-a-net-assembly-into-a-separate-appdomain-so-you-can-unload-it/

Many thanks :)


回答1:


As mentioned already, loading the assembly from bytes can only happen for the current app domain.

Here is one way to context-switch to make your target app domain the current one, using the DoCallBack method on the app domain (http://msdn.microsoft.com/en-us/library/system.appdomain.docallback%28v=vs.110%29.aspx).

After the assemblies are loaded you can then use the same method to inspect the assemblies and types of the new app domain, and create instances as necessary, before unloading it.

class Program
{
    static void Main(string[] args)
    {
        AppDomain newDomain = AppDomain.CreateDomain("NewDomain");
        List<string> dllPaths = new List<string>() { @"c:\dev\taglib-sharp.dll" };

        foreach (string dll in dllPaths)
        {
            AppDomainAsmLoader asmLoad = new AppDomainAsmLoader(File.ReadAllBytes(dll));
            newDomain.DoCallBack(new CrossAppDomainDelegate(asmLoad.LoadAsm));
        }

        newDomain.DoCallBack(new CrossAppDomainDelegate(DoWorkWithAppDomain));

        AppDomain.Unload(newDomain);
        Console.ReadKey();
    }

    public static void DoWorkWithAppDomain()
    {
        Assembly[] asms = AppDomain.CurrentDomain.GetAssemblies();
        foreach (Assembly asm in asms)
        {
            Type[] types = asm.GetTypes();
            foreach (Type type in types)
            {
                Console.WriteLine("Found the type: {0}", type.FullName);
            }
        }
    }

    [Serializable]
    public class AppDomainAsmLoader
    {
        private byte[] AsmData;  

        public AppDomainAsmLoader(byte[] data)
        {
            AsmData = data;
        }         

        public void LoadAsm()
        {
            Assembly asm = Assembly.Load(AsmData);
        }

    }
}



回答2:


As Erik suggested, you need to use CreateInstanceAndWrap. Here's an example I did in VB a while back...

Private Function GetCoupler() As IBatchCoupler
        Dim CouplerProxy As IBatchCoupler = Nothing
        Try
            Dim DomainSetupInfo As AppDomainSetup = New AppDomainSetup()
            DomainSetupInfo.ConfigurationFile = Path.Combine(mFilePath, "web.config")
            DomainSetupInfo.ApplicationBase = Path.Combine(mFilePath, "bin")
            DomainSetupInfo.ShadowCopyFiles = "true"

Dim domain As AppDomain = AppDomain.CreateDomain("CoolDomain", AppDomain.CurrentDomain.Evidence, DomainSetupInfo)

            'Create remote object in new appDomain via the coupler interface
            'to avoid loading the design library into the calling application's primary appDomain
            CouplerProxy = domain.CreateInstanceFromAndUnwrap(Path.Combine(DomainSetupInfo.ApplicationBase, "Design.dll"), "BigApplication.Design.BatchCoupler")

        Catch ex As Exception

            ThisLogger.Error(ex)
        End Try
        Return CouplerProxy
    End Function


来源:https://stackoverflow.com/questions/27071379/load-assembly-into-a-new-app-domain-but-not-currentdomain

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!