2012-10-26 43 views
12

我現在正在爲AssenblyResolve事件苦苦掙扎。我搜索了stackoverflow,並做了其他Google搜索,並嘗試了所有我認爲相關的內容。這裏有被越接近我的問題(在我看來)鏈接:AssemblyResolve未被依賴關係解僱

  1. AssemblyResolve is not invoked and FileNotFoundException is thrown during serialization

  2. Where to handle AssemblyResolve event in a class library?

我有靜態方法的引導程序類(我將刪除我們有的線程安全代碼,只是爲了清晰起見:

public static void Initialize() 
{ 
    AppDomain.CurrentDomain.AssemblyResolve += CustomResolve; 
} 

private static Assembly CustomResolve(object sender, ResolveEventArgs args) 
{ 
    // There is a lot code here but basicall what it does. 
    // Is determining which architecture the computer is running on and 
    // extract the correct embedded dll (x86 or x64). The code was based 
    // on milang on GitHub (https://github.com/milang/P4.net). And it's the same 
    // purpose we want to be able to load the x86 or x64 version of the perforce dll 
    // but this time with the officially Perforce supported p4api.net. 
    // Once the dll is extracted we assign it to the boostrapper 
    Bootstrapper._p4dnAssembly = Assembly.LoadFile(targetFileName); 

    // Make sure we can satisfy the requested reference with the embedded assembly (now extracted). 
    AssemblyName reference = new AssemblyName(args.Name); 
    if (AssemblyName.ReferenceMatchesDefinition(reference, Bootstrapper._p4dnAssembly.GetName())) 
    { 
     return Bootstrapper._p4dnAssembly; 
    } 
} 

我能夠使代碼工作,如果我有一個主要方法和靜態構造函數的簡單類。靜態構造函數只是簡單地調用Boostrapper.Initialize()方法。 之後,我可以用我的圖書館,它按預期工作:

public static class Test 
{ 
    static Test() 
    { 
     Bootstrapper.Initialize(); 
    } 

    public static void Main() 
    { 
     // Using the library here is working fine. The AssemblyResolve event was 
     // fired (confirmed by a breakpoint in Visual Studio) 
    } 
} 

我的問題是,如果有相關性至少一層。基本上,代碼保持不變,但是這一次我的圖書館的代碼是另一個庫中:

public static class Test 
{ 
    static Test() 
    { 
     Bootstrapper.Initialize(); 
    } 

    public static void Main() 
    { 
     Class1 myClass = new Class1(); 

     // The following line is using the code of the extracted library, but 
     // The AssemblyResolve event is not fired (or fired before I register the 
     // callback) and therefore the library is not found : result 
     // BadImageFormatException() error could not load libary because one 
     myClass.Connect(); 
    } 
} 

聽起來#我前面提到的鏈接2解釋我所看到的,但它不工作。 AssemblyResove回調上的Visual Studio斷點永遠不會被擊中。

想知道發生了什麼?

弗朗西斯

回答

7

有人做的答案,但答案已被刪除。所以我不能將它標記爲已回答。 基本上,代碼不需要超出「主要」方法的事實正在發揮作用。 開始從一個新項目的新鮮,解決這個問題,所以我想我有一些問題的dll

static void main(string[] args) 
{ 
    Boostrapper.Initialize(); 
    RealMain(); 
} 

static void RealMain() 
{ 
    Class1 myClass = new Class1(); 
    myClass.Connect(); 
} 
15

(在x64文件夾或反之亦然大概86 DLL),我知道它已經有一段時間,因爲這個問題是問和答覆,但我想在這個問題上增加我的意見(因爲我只是浪費了幾個小時過來,也許要感謝這個別人不會有)

問題基本上是這樣的事實,即應用程序試圖解析在該方法開始時執行該方法所需的所有程序集:

static void main(string[] args) 
{ 
    // <-- here the app tries to resolve MyAssembly 
    // and as MyAssembly.Class1 is not found, the app crashes 

    // this next line is never called: 
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolveAssembly); 

    // class contained in an assemnly that we need to resolve 
    MyAssembly.Class1 myClass = new MyAssembly.Class1(); 
} 

這就是爲什麼上述情況會崩潰的原因:ResolveAssembly事件處理程序永遠不會被調用,因爲它永遠不會被連接。

而且這也是爲什麼下面的解決方案工作(如發佈由OP):

static void main(string[] args) 
{ 
    Initialize(); 
    RealMain(); 
} 

static void Initialize() 
{ 
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolveAssembly); 
} 

static void RealMain() 
{ 
    // <-- here the app tries to resolve MyAssembly 
    // class contained in an assemnly that we need to resolve  
    MyAssembly.Class1 myClass = new MyAssembly.Class1(); 
    // and everything is OK 
}