创建的 AppDomain 上的 AssemblyResolve 事件出现问题
我试图通过将 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;
}
// ...
}
执行此代码时,FooProperty 未在 Domain_AssemblyResolve 事件处理程序中初始化,并且 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");
你知道发生了什么吗?或者一些解决方法?
谢谢!
I am trying to customize the assembly resolution process by wrapping the AppDomain
and its AssemblyResolve
event inside a class. The simplified version of my ClassLoader
is below. The problem I am having is that when the event AssemblyResolve
is fired, it seems that I get a new instance of ClassLoader
, not the one I previously created.
[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;
}
// ...
}
When executing this code, FooProperty is not initialized in the Domain_AssemblyResolve event handler and the ClassLoader instance has a different hash code from "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");
Do you what is happening? or some workaround?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
ClassLoader
实例c
是在应用程序域A
上创建的,由于它不是从MarshalByRefObject
继承的,因此它将被序列化将事件处理程序添加到AssemblyResolve
时创建的应用程序域中。发生这种情况是因为该方法是实例方法,并且委托需要对调用该方法的目标对象的引用。如果您只是希望 FooProperty 在触发事件处理程序时具有特定值,那么您可以仅在初始化属性后添加事件处理程序,从而使该值被序列化并在新创建的应用程序域中可用。
如果您要求实例
c
在两个应用程序域中都可用,那么您应该查看:使对象可远程
使用 .NET Framework 远程处理的事件和委托
The
ClassLoader
instancec
is created on application domainA
and since it does not inherits fromMarshalByRefObject
it will be serialized into the application domain that you are creating at the moment you add the event handler toAssemblyResolve
. This happens because the method is an instance method and the delegate will need a reference to the target object where the method will be called.If you just want that the
FooProperty
have a specific value when the event handler is triggered then you can add the event handler only after initializing the property causing the value to be serialized and available in the newly created application domain.If you have the requirement that the instance
c
is available in both application domains then you should take a look at:Making Objects Remotable
Events and Delegates with .NET Framework Remoting
出色地,
处理程序内似乎没有任何初始化
Foo
的代码。从 Object 继承的类实例(例如 ClassLoader)并且不重新实现 GetHashCode()(如您的情况),都将具有不同的哈希代码(基于地址)的对象)。如果您想要基于内部状态的一致代码,请重写
GetHashCode()
。Well,
There doesn't seem to be any code that initialises
Foo
inside the handler.Instances of classes that inherit from Object (like
ClassLoader
) and don't reimplementGetHashCode()
, like in your case, will all have different hash codes (based on the address of the object). OverrideGetHashCode()
if you want consistent codes based on internal state.