我正在尝试通过将AppDomain及其AssemblyResolve事件包装在一个类中来定制程序集解析过程。下面是我的ClassLoader的简化版本。我遇到的问题是,当事件AssemblyResolve被触发时,我似乎得到了一个新的ClassLoader实例,而不是我之前创建的那个实例。
[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;
}
// ...
}执行此代码时,不会在Domain_AssemblyResolve事件处理程序中初始化FooProperty,并且ClassLoader实例具有与"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");你知道发生了什么吗?或者一些解决方法?
谢谢!
发布于 2010-06-30 18:55:44
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
发布于 2010-06-30 18:35:54
井,
执行此代码时,不会在Domain_AssemblyResolve事件中初始化FooProperty
在处理程序中似乎没有任何初始化Foo的代码。
ClassLoader实例具有与"c“不同的哈希码。
继承自Object的类的实例(如ClassLoader)并且没有重新实现GetHashCode(),就像您的例子一样,它们都有不同的散列码(基于对象的地址)。如果您希望基于内部状态的代码一致,请覆盖GetHashCode()。
https://stackoverflow.com/questions/3148316
复制相似问题