如何在Castle DynamicProxy中处理受保护的泛型重载?

时间:2017-07-03 07:46:31

标签: c# generics moq castle castle-dynamicproxy

我遇到了为具有重载方法签名的通用对象创建Castle DynamicProxy的问题。我最初通过Moq遇到了这个问题,但我能够通过手动生成一个相当简单的代理来重现相同的Exception:

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 { }

代理创建失败,出现以下异常:

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

以下黑客修复了问题,但依赖于对类定义的更改:

  • 重命名其中一种方法,以便它们不再过载。
  • 重新排序类中的代码,以便在受保护的方法之前定义公共方法。

有没有办法在不修改依赖项代码的情况下创建代理?

0 个答案:

没有答案