2016-09-14 43 views
0

我有一個程序集(MyAssembly.dll)(有點像包裝),其中有幾個引用其他程序集(3rdAssembly1.dll,3rdAssembly2.dll)。這些引用的程序集作爲嵌入式資源嵌入我的程序集中。在我的程序集中,我有主類(MyClass),它從這些第三方程序集中調用了一些函數。這個類有一個默認的構造函數,我嘗試解決所需的依賴關係如下:放在一起所有程序集並將其用作嵌入式資源在exe中

public MyClass{ 
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(Resolver); 
} 

public static System.Reflection.Assembly Resolver(object sender, ResolveEventArgs args) 
{ 
    string source = "MyAssembly.Resources."+args.Name.Remove(args.Name.IndexOf(','))+".dll"; 
    //source = "MyAssembly.Resources.3rdAssembly1.dll" 
    //source = "MyAssembly.Resources.3rdAssembly2.dll" 

    Assembly a1 = Assembly.GetExecutingAssembly(); 
    Stream s = a1.GetManifestResourceStream(source); 
    byte[] block = new byte[s.Length]; 
    s.Read(block, 0, block.Length); 
    Assembly a2 = Assembly.Load(block); 
    return a2; 
} 

然後我嘗試使用我的組件(MyAssembly.dll程序)嵌入資源在我的主機應用程序(MyApp.exe將),我也使用Resolver函數。

static void main(string[] args){ 
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(MainResolver); 

    MyClass my = new MyClass(); 
    my.DoWork(); 
} 

static System.Reflection.Assembly MainResolver(object sender, ResolveEventArgs args) 
{ 
    string source = "MyApp.Resources."+args.Name.Remove(args.Name.IndexOf(','))+".dll"; 
    //source = "MyApp.Resources.MyAssembly.dll" 
    Assembly a1 = Assembly.GetExecutingAssembly(); 
    Stream s = a1.GetManifestResourceStream(args.Name); 
    byte[] block = new byte[s.Length]; 
    s.Read(block, 0, block.Length); 
    Assembly a2 = Assembly.Load(block); 
    return a2; 
} 

的問題是我的主機應用程序不解決內部組件(3rdAssembly1.dll,3rdAssembly2.dll),因爲在MyClass的Resolver功能不會被調用。主機應用程序嘗試解決所有這些問題,結果失敗。我玩弄了它,發現如果我從嵌入式資源中排除MyAssembly.dll,並找到它在與主機應用程序相同的文件夾中,並替換+= new ResolveEventHandler(MainResolver)+= new ResolveEventHandler(MyClass.Resolver)main函數然後它的工作! 有必要有一個程序集,因爲我打算在幾個應用程序中使用它,並且我不希望每次都在所有應用程序中包含所有引用的程序集。

所以,我的問題是如何解決主機應用程序中的所有依賴項(MyAssembly.dll和MyAssembly.dll中包含的所有內部的依賴作爲嵌入式資源)?

在此先感謝!

回答

0

我解決了這個問題。當主機應用程序運行並且找不到所需的程序集時,它會調用AssemblyResolve事件。所以,我必須使用名爲MainResolver的事件處理程序來加載MyAssembly.dll。然後,在使用MyAssembly.dll的方法之前,需要將其從AssemblyResolve中刪除,因爲該應用試圖通過使用ResolveEventHandler來添加它們(它調用MainResolver,然後Resolver)來解決依賴關係。因此主機應用程序失敗,因爲它無法在MainResolver中找到所需的程序集。解決方法是在調用ResolveEventHandler或從AssemblyResolve中刪除MainResolver。我認爲排除無用的處理程序更容易。

因此,我不需要更改MyClass中的任何內容。我需要的一切就是在創建MyClass實例之前在主機應用程序中添加以下代碼。

static MyApp(){ 
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(MainResolver); 
} 

static void main(string[] args){ 
    //remove MainResolver 
    AppDomain.CurrentDomain.AssemblyResolve -= MainResolver; 

    MyClass my = new MyClass(); 
    my.DoWork(); 
} 

現在它就像一個魅力!

相關問題