I'm encountering a problem creating a Castle DynamicProxy for a generic object with an overloaded method signature. I originally ran into the problem via Moq, but I was able to reproduce the same Exception by generating a fairly simple proxy manually:
using Castle.DynamicProxy;
using NUnit.Framework;
[TestFixture]
public class TestOverloadedMethods
{
[Test]
public void ProxyCreationFails()
{
var generator = new ProxyGenerator();
generator.CreateClassProxy(typeof(SomeDependency<SomeParam>),
ProxyGenerationOptions.Default, new object[] { });
}
}
public abstract class SomeDependency<T>
{
protected virtual void Do(T param) { }
public virtual void Do(SomeParam param) { }
}
public class SomeParam { }
The proxy creation fails with the following Exception:
System.TypeLoadException : Derived method 'Do' in type 'Castle.Proxies.SomeDependency`1Proxy'
from assembly 'DynamicProxyGenAssembly2' cannot reduce access.
at System.Reflection.Emit.TypeBuilder.TermCreateClass(RuntimeModule module, Int32 tk, ObjectHandleOnStack type)
at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
at System.Reflection.Emit.TypeBuilder.CreateTypeInfo()
at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.CreateType(TypeBuilder type)
at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType()
at Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateType(String name, Type[] interfaces, INamingScope namingScope)
at Castle.DynamicProxy.Generators.BaseProxyGenerator.ObtainProxyType(CacheKey cacheKey, Func`3 factory)
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors)
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors)
at TestAmbiguousMethods.ProxyCreationFails() in TestOverloadedMethods.cs:line 11
The following hacks fix the problem but rely on changes to the class definition:
- Rename one of the methods, so they're no longer overloaded.
- Reorder the code in the class, so that the public method is defined before the protected method.
Is there a way to create the proxy without modifying the code for the dependency?