2010-06-30 19 views
2

我試圖通過將AppDomain及其AssemblyResolve事件包裝到類中來自定義程序集解析過程。下面是我的ClassLoader的簡化版本。我遇到的問題是當事件AssemblyResolve被解僱時,似乎我得到一個新的ClassLoader實例,而不是我之前創建的實例。創建的AppDomain上的AssemblyResolve事件的問題

[Serializable] 
public class ClassLoader // : IDisposable 
{ 
    public AppDomain Domain { get; private set; } 
    public string FooProperty { get; set; } 

    public ClassLoader(string domain) { 
     Domain = AppDomain.CreateDomain(domain); 
     Domain.AssemblyResolve += Domain_AssemblyResolve; 
    } 

    private Assembly Domain_AssemblyResolve(object sender, ResolveEventArgs args) 
    { 
     Console.WriteLine(
      "ClassLoader HashCode: {0} FooProperty: {1}\n\n", 
      GetHashCode(), 
      FooProperty); 
     // ... 
     return null; 
    } 
    // ... 
} 

當執行此代碼,FooProperty未在Domain_AssemblyResolve事件處理程序初始化,類加載器實例具有從「c」不同的散列碼。

var c = new ClassLoader("demo"); 
c.FooProperty = "Foo"; 
Console.WriteLine(
    "c Hash Code: {0} FooProperty: {1}", 
    c.GetHashCode(), 
    c.FooProperty); 
c.Domain.CreateInstanceAndUnwrap("Not important", "Not important"); 

你是怎麼回事?或一些解決方法?

謝謝!

回答

2

ClassLoader實例c是在應用領域A創建,因爲它不從MarshalByRefObject繼承將序列化爲正在創建你的事件處理程序添加到AssemblyResolve此刻應用領域。發生這種情況是因爲該方法是一種實例方法,委託將需要對該方法將被調用的目標對象的引用。

如果你只是想的FooProperty有一個特定的值時觸發事件處理程序,那麼你只能初始化屬性導致新創建的應用程序域被序列化的價值和可後添加事件處理程序。

public string FooProperty { get; private set; } 

public ClassLoader(string domain, string fooProperty) 
{ 
    FooProperty = fooProperty; // Set it before adding event handler 
    Domain = AppDomain.CreateDomain(domain); 
    Domain.AssemblyResolve += Domain_AssemblyResolve; 
} 

如果您有實例c可在這兩個應用領域的需求,那麼你應該看看:

Making Objects Remotable

Events and Delegates with .NET Framework Remoting

0

好,

執行此代碼時,FooProperty 沒有在 Domain_AssemblyResolve事件

似乎沒有對是初始化Foo的處理程序中的任何代碼初始化。

ClassLoader實例具有 與「c」不同的哈希碼。

實例,從對象(如ClassLoader)繼承和你的情況不重新實現GetHashCode()一樣,都將有不同的散列碼(基於對象的地址)班。如果您想要基於內部狀態的一致代碼,請覆蓋GetHashCode()

相關問題