Question

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.coma 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?

Was it helpful?

Solution

I fixed the issue partially. I noticed that the exception throws only on specific classes. For example:

public virtual ObjectTypeFromThirdPartySignedAssembly PropertyName { get; set; }

public virtual ObjectTypeFromThirdPartySignedAssembly MethodName()
{
}

public virtual void Method2(ObjectTypeFromThirdPartySignedAssembly inputObject)
{
}

As can be seen, the proxy works here directly with dependencies. Since I found the root of problem, I skipped these classes from proxifying. This is not the best solution, of course, nonetheless I could use logging, error handling and other interceptors to wrap a part of my classes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top