代码之家  ›  专栏  ›  技术社区  ›  Alexander Petrovskiy

如何强制Castle.DynamicProxy忽略依赖项的更改版本

  •  1
  • Alexander Petrovskiy  · 技术社区  · 11 年前

    我使用 Castle.DynamicProxy 用于AOP。我的IoC容器是 Ninject 3.2 在它返回已解析的依赖项后,我将大部分依赖项放到基于Castle的包装器中。(我不能用 Ninject.Extensions.Interception 因为它与 Ninject.Extensions.Conventions for NInject 3.0.1.0/3.2 )

    问题是我的代码依赖于每天都在变化的二进制文件(签名的程序集)(我的代码是一系列产品的测试框架)。如果程序集附带新版本,Castle将开始抛出异常“ There was an error in static constructor on type Castle.Proxies.[MyClassName]Proxy. This is likely a bug in DynamicProxy. Please report it.".

    我与Castle的代码:

    internal static T ResolveAndProxify<T>(object[] arguments, params IParameter[] parameters) where T : class
    {
        var objectToProxy = default(T);
        if (null == parameters || 0 == parameters.Length) {
            objectToProxy = _kernel.Get<T>(new IParameter[] {});
        } else {
            objectToProxy = _kernel.Get<T>(parameters);
        }
        if (/* condition not to proxify */) {
            return objectToProxy;
        } else {
            if (null == arguments || 0 == arguments.Length) {
                return (T)_proxyGenerator.CreateClassProxy(
                    typeof(T),
                    new LoggingAspect(), new ErrorHandlingAspect());
            } else {
                return (T)_proxyGenerator.CreateClassProxy(
                    typeof(T),
                    arguments,
                    new LoggingAspect(), new ErrorHandlingAspect());
            }
        }
    }
    

    如果我关闭Castle,所有工作:

    internal static T ResolveAndProxify<T>(object[] arguments, params IParameter[] parameters) where T : class
    {
        var objectToProxy = default(T);
        if (null == parameters || 0 == parameters.Length) {
            objectToProxy = _kernel.Get<T>(new IParameter[] {});
        } else {
            objectToProxy = _kernel.Get<T>(parameters);
        }
    
        return objectToProxy;
    }
    

    城堡组件的声明和创建:

    private static readonly ProxyGenerator _proxyGenerator;
    
    // I tried several ways
    var scope = new ModuleScope(false, true);
    var proxyBuilder = new DefaultProxyBuilder(scope);
    var proxyArgument = new ConstructorArgument("builder", proxyBuilder);
    _proxyGenerator = _kernel.Get<ProxyGenerator>(proxyArgument);
    
    Bind<ProxyGenerator>().ToConstructor(arg => new ProxyGenerator(arg.Inject<IProxyBuilder()));
    

    我在这里看到了 stackoverflow.com 一个示例(在评论中)如何关闭缓存或将Castle与程序集的精确版本联系起来,例如Castle Windsor。如何在没有 Castle Windsor ?

    1 回复  |  直到 11 年前
        1
  •  1
  •   Alexander Petrovskiy    10 年前

    我部分解决了这个问题。 我注意到,异常只在特定的类上抛出。 例如:

    public virtual ObjectTypeFromThirdPartySignedAssembly PropertyName { get; set; }
    
    public virtual ObjectTypeFromThirdPartySignedAssembly MethodName()
    {
    }
    
    public virtual void Method2(ObjectTypeFromThirdPartySignedAssembly inputObject)
    {
    }
    

    可以看出,代理在这里直接使用依赖项工作。既然我找到了问题的根源,我就跳过了这些代理类。当然,这不是最好的解决方案,但我可以使用日志记录、错误处理和其他拦截器来包装我的一部分类。