我将Castle.DynamicProxy
用于AOP。我的IoC容器是Ninject 3.2
,在它返回已解析的依赖项后,我将它们中的大多数放在基于城堡的包装器中。 (我无法使用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.".
我的城堡代码:
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;
}
宣布并创建Castle组件:
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
的情况下做同样的事情?
答案 0 :(得分:1)
我部分解决了这个问题。 我注意到异常只会抛出特定的类。 例如:
public virtual ObjectTypeFromThirdPartySignedAssembly PropertyName { get; set; }
public virtual ObjectTypeFromThirdPartySignedAssembly MethodName()
{
}
public virtual void Method2(ObjectTypeFromThirdPartySignedAssembly inputObject)
{
}
可以看出,代理在这里直接使用依赖项。由于我找到了问题的根源,我从代理中跳过了这些类。当然,这不是最佳解决方案,但我可以使用日志记录,错误处理和其他拦截器来包装我的一部分类。