将程序集加载到一个新的应用程序域,但不是CurrentDomain

问题描述:

所以我的问题围绕节省内存。将程序集加载到一个新的应用程序域,但不是CurrentDomain

实质上,我需要将程序集加载到主/当前域以外的单独应用程序域中,检查该程序集中的类型,然后在完成时卸载新的域。

目前我的解决方案如下:

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); 

的NewDomain.Load线似乎装配加载到新的领域,但也到我的程序的当前域。

我用这个链接作为参考 - http://www.csharp411.com/how-to-load-a-net-assembly-into-a-separate-appdomain-so-you-can-unload-it/

非常感谢:)

+1

我不知道是否有什么关系的文件['AppDomain.Load方法(Byte [])'](http://msdn.microsoft.com/en-us/library/7hcs6az6% 28v = vs.110%29.aspx)表示'这种方法只能用于将程序集加载到当前应用程序域中。 ...要将程序集加载到其他应用程序域中,请使用诸如CreateInstanceAndUnwrap.'之类的方法 – 2014-11-21 22:36:18

正如埃里克建议,你需要使用CreateInstanceAndWrap。这里有一个例子,我在VB中做了一段时间...

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 

如前所述,从字节加载程序集只能发生在当前应用程序域。

下面是使用应用程序域上的DoCallBack方法(http://msdn.microsoft.com/en-us/library/system.appdomain.docallback%28v=vs.110%29.aspx)上下文切换以使目标应用程序域成为当前应用程序域的一种方法。

加载程序集后,您可以使用相同的方法检查新应用程序域的程序集和类型,并在卸载它之前根据需要创建实例。

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); 
     } 

    } 
}