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
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);
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>()
});