We added DynamicProxy to our ASP.NET web app a couple of weeks ago. The code ran fine in dev and QA, but when we pushed to production, we got the following exception (top of stack trace only):
[ArgumentNullException: Invalid internal state.]
System.Reflection.Emit.TypeBuilder._InternalSetMethodIL(Int32 methodHandle, Boolean isInitLocals, Byte[] body, Byte[] LocalSig, Int32 sigLength, Int32 maxStackSize, Int32 numExceptions, __ExceptionInstance[] exceptions, Int32[] tokenFixups, Int32[] rvaFixups, Module module) +0 System.Reflection.Emit.TypeBuilder.InternalSetMethodIL(Int32 methodHandle, Boolean isInitLocals, Byte[] body, Byte[] LocalSig, Int32 sigLength, Int32 maxStackSize, Int32 numExceptions, __ExceptionInstance[] exceptions, Int32[] tokenFixups, Int32[] rvaFixups, Module module) +56 System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() +1033 System.Reflection.Emit.TypeBuilder.CreateType() +99 Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.CreateType(TypeBuilder type) +72 Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType() +96 Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateType(String name, Type[] interfaces, INamingScope namingScope)开发者_运维百科 +854 Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateCode(Type[] interfaces, ProxyGenerationOptions options) +834 Castle.DynamicProxy.DefaultProxyBuilder.CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options) +133 Castle.DynamicProxy.ProxyGenerator.CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options) +52 Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors) +308 Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors) +48 Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors) +44
It worked fine when we first pushed the code, and an IIS reset fixed it, so I'm assuming it's thread related, but I couldn't find anything on the interwebs regarding best practices for thread-safety proxy generation. Suggestions?
UPDATE: After reading some more on the issue, especially here, I realized one potential issue -- namely that I had not overwritten Equals/GetHashCode for the implementation of IProxyGenerationHook I had written, which would prevent DynamicProxy from caching it's types. As I can find next to nothing on the exception I saw in general let alone related to DP, I'm gonna assume that it was the lack of caching of types caused by my omission that was the root cause of the problem, though I'd love a confirmation.
For the record, my object creation is pretty vanilla:
private T CreateProxy(MyArgs args)
{
var options = new ProxyGenerationOptions(new MyMethodSelector());
options.AddMixinInstance(new MyMixin());
return Generator.CreateClassProxy(
TargetType,
options,
new[] { new MyInterceptor(args) }) as T;
}
actually DynamicProxy is thread safe so it is quite unlikely it is concurrency related.
First of all, which version of DynamicProxy are you using?
Are you able to reproduce the issue in isolation, outside of IIS?
This issue was reported two years ago, but it was fixed. Please make sure you have the latest version.
精彩评论