Search code examples
c#wcfunity-containerinterceptor

Getting System.StackOverflowException with Unity Interceptor in WCF


I'm setting interceptors from Unity into my WCF project and I get a System.StackOverflowException when I call a method from my service. This comes from Interceptors I set up but I don't know how to solve it.

FYI: I check if I had a circular dependancy or a non-terminating recursion

I'm using Unity v4 and Unity.WCF v3.0

Here's the code

the Factory for the web service

public class WcfServiceFactory : UnityServiceHostFactory
{
    protected override void ConfigureContainer(IUnityContainer container)
    {
        // register all your components with the container here
        List<string> lstNomAssemblyToLoad = new List<string>();
        List<Assembly> lstAssemblyToLoad;

        lstNomAssemblyToLoad.Add("Service");
        lstNomAssemblyToLoad.Add("Interfaces");
        lstNomAssemblyToLoad.Add("Bll");
        lstNomAssemblyToLoad.Add("Dal");

        // Loading specific interface from unity.config
        container = container.LoadConfiguration();

        // Resolving interfaces without explicit declaration
        lstAssemblyToLoad = AppDomain.CurrentDomain.GetAssemblies().Where(a => lstNomAssemblyToLoad.Contains(a.GetName().Name)).ToList();
        container.AddNewExtension<Interception>();
        container.RegisterTypes(AllClasses.FromAssemblies(lstAssemblyToLoad),
                                WithMappings.FromAllInterfaces,
                                WithName.Default,
                                WithLifetime.ContainerControlled, 
                                getInjectionMembers: c => new InjectionMember[]
                                {
                                    new Interceptor<VirtualMethodInterceptor>(),
                                    new InterceptionBehavior<ExceptionInterceptionBehavior>()
                                }, 
                                overwriteExistingMappings: true);

    }
} 

My InterceptionBehavior

public class ExceptionInterceptionBehavior : IInterceptionBehavior
{
    public IEnumerable<Type> GetRequiredInterfaces()
    {
        return Type.EmptyTypes;
    }

    public bool WillExecute
    {
        get { return true; }
    }

    public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
    {
        var result = getNext()(input, getNext);
        return result;
    }
}

Any ideas why I get An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll every time I'm calling a method of my web service ?

The trace

enter image description here

If you need more information please do not hesitate to ask.

Thank for the help


UPDATE

If I remove interceptors, of course I do not have exception anymore:

container.RegisterTypes(AllClasses.FromAssemblies(lstAssemblyToLoad),
                                WithMappings.FromAllInterfaces,
                                WithName.Default,
                                WithLifetime.ContainerControlled, 
                                null, 
                                overwriteExistingMappings: true);

But If I change just WithName.Default to WithName.TypeName and keep interceptors, I don't get exception... I don't understand why...

container.RegisterTypes(AllClasses.FromAssemblies(lstAssemblyToLoad),
                                WithMappings.FromAllInterfaces,
                                WithName.TypeName,
                                WithLifetime.ContainerControlled, 
                                getInjectionMembers: c => new InjectionMember[]
                                {
                                    new Interceptor<VirtualMethodInterceptor>(),
                                    new InterceptionBehavior<ExceptionInterceptionBehavior>()
                                }, 
                                overwriteExistingMappings: true);

Solution

  • I found a workaround by setting getName to WithName.TypeName or t => t.GetType().Name but now I'm facing a mapping issue :)

    However I still don't know why this is solving the StackOverflowException. If anyone knows, I'll give him a cookie.

    EDIT With my colleague we reviewed it and found this solution Registration by convention and interception causes ResolutionFailedException

    So we add a new Type filter

    public static class TypeFiltres
    {
        public static IEnumerable<Type> WithMatchingInterface(this IEnumerable<Type> types)
        {
            return types.Where(type =>
                type.GetTypeInfo().GetInterface("I" + type.Name) != null);
        }
    }
    

    and changed the configuration into the WCF Factory like this

    container.RegisterTypes(AllClasses.FromAssemblies(lstAssemblyToLoad).WithMatchingInterface(),
                                    WithMappings.FromMatchingInterface,
                                    WithName.Default,
                                    WithLifetime.ContainerControlled,
                                    getInjectionMembers: c => new InjectionMember[]
                                    {
                                        new Interceptor<InterfaceInterceptor>(),
                                        new InterceptionBehavior<ExceptionInterceptionBehavior>()
                                    });