如果您执行以下代码:
var appDomain = AppDomain.CreateDomain("some domain");
var assembly = appDomain.Load(someAssemblyBytes);
将会生成一个
AssemblyResolve
事件。这是因为该程序集已加载到两个域中。第一个域是您期望的域,即
appDomain
,并且该域的程序集解析器未被调用。第二个域是您当前的应用程序域,因为您尝试从中访问该程序集,而它在那里不存在。
因此,如果您从与
appDomain
不同的域执行
appDomain.Load(someAssemblyName);
,则将生成两次解析事件,每个域一次。
在这种情况下,如果您想要省略AssemblyResolve尝试(它将失败或也将加载程序集到主域中),您必须创建一个代理类,该类派生自
MarshalByRefObject
,在两个域中都可见的程序集中使用此代理类来包含代理类。例如:
internal class AssemblyVersionProxy : MarshalByRefObject
{
public Version GetVersion(byte[] assemblyBytes)
{
var assembly = Assembly.Load(assemblyBytes);
var version = new AssemblyName(assembly.FullName).Version;
return version;
}
}
并使用它:
public Version GetAssemblyVersion(byte[] assemblyBytes)
{
var appDomain = AppDomain.CreateDomain(Guid.NewGuid().ToString());
try
{
var proxyType = typeof(AssemblyVersionProxy);
var proxy = (AssemblyVersionProxy)appDomain.CreateInstanceAndUnwrap(
proxyType.Assembly.FullName, proxyType.FullName,
false, BindingFlags.CreateInstance, null,
new object[0], null, new object[0]
);
var version = proxy.GetVersion(assemblyBytes);
return version;
}
finally
{
AppDomain.Unload(appDomain);
}
}
assembly:
属性,会发生什么? - chillitom<Module>
类型的静态构造函数,该类型包含在模块中声明的所有全局成员。只有当第一次访问某个全局成员时,才会调用模块初始化程序。@HansPassant - Vladimir Reshetnikov