我正在生成自己的代理来包装从MongoDB返回的对象。 代理实现一个接口:
interface IProxy
{
string __ID {get;}
}
代理生成器使用以下代码生成实现
PropertyBuilder proxyID = typeBuilder.DefineProperty("__ID", PropertyAttributes.None, typeof(string), null);
proxyID.SetCustomAttribute(new CustomAttributeBuilder(typeof(Root.Attributes.DataAnnotations.NotMappedAttribute).GetConstructor(Type.EmptyTypes), new object[0]));
MethodBuilder proxyID_PropertyGet = typeBuilder.DefineMethod("get___ID", MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, typeof(string), Type.EmptyTypes);
ILGenerator __IDILget = proxyID_PropertyGet.GetILGenerator();
__IDILget.Emit(OpCodes.Ldarg_0);
__IDILget.Emit(OpCodes.Ldfld, objectID);
__IDILget.Emit(OpCodes.Callvirt, typeof(ObjectId).GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance));
__IDILget.Emit(OpCodes.Ret);
proxyID.SetGetMethod(proxyID_PropertyGet);
应用程序使用"任何 CPU"配置进行编译。
当使用Visual Studio Web服务器在我们的开发计算机上运行时,应用程序工作正常。
在 IIS7.5 (Windows 2008 R2) 上运行时,每当访问 __ID 属性时,它都会引发无效的程序异常。 将"启用 32 位应用程序"设置更改为 true 会更改此行为。
我不想修改 IIS 配置。 为什么仅在 64 位应用程序中引发异常?
事实证明,调用字段 ToString() 是一个结构体,因此 IL 必须更改为:
ILGenerator __IDILget = proxyID_PropertyGet.GetILGenerator();
__IDILget.Emit(OpCodes.Ldarg_0);
__IDILget.Emit(OpCodes.Ldflda, objectID);
__IDILget.Emit(OpCodes.Constrained, typeof(ObjectId));
__IDILget.Emit(OpCodes.Callvirt, typeof(ObjectId).GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance));
__IDILget.Emit(OpCodes.Ret);
proxyID.SetGetMethod(proxyID_PropertyGet);