I use Castle.DynamicProxy
for AOP. My IoC container is Ninject 3.2
and after it returns resolved dependencies, I put the most of them to a Castle-based wrapper. (I can't use Ninject.Extensions.Interception
as it conflicts with Ninject.Extensions.Conventions for NInject 3.0.1.0/3.2
)
The problem is that my code depends on binaries (signed assemblies) that change everyday (my code is a test framework for a bunch of products). If an assembly ships with a new version, Castle begins throwing an exception "There was an error in static constructor on type Castle.Proxies.[MyClassName]Proxy. This is likely a bug in DynamicProxy. Please report it.".
My code with 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());
}
}
}
If I turn off Castle, all works:
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;
}
Declaration and creation of Castle compoments:
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()));
I saw here at stackoverflow.com
a sample (in the comments) how to switch off caching or something that ties Castle to an exact version of the assembly, for Castle Windsor. How to do the same without Castle Windsor
?