在WCF中使用Unity Interceptor获取System.StackOverflowException

时间:2017-09-06 12:30:01

标签: c# wcf unity-container interceptor

我将Unity中的拦截器设置到我的WCF项目中,当我从服务中调用方法时,我得到System.StackOverflowException。这来自我设置的拦截器,但我不知道如何解决它。

仅供参考:我检查是否有circular dependancya non-terminating recursion

我使用的是Unity v4和Unity.WCF v3.0

这是代码

Web服务工厂

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

为什么每次我调用我的网络服务方法时都会得到An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll的任何想法?

追踪

enter image description here

如果您需要更多信息,请不要犹豫。

感谢您的帮助

更新

如果我删除拦截器,我当然不会有例外:

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

但如果我将WithName.Default更改为WithName.TypeName并保留拦截器,我就不会例外......我不明白为什么......

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

1 个答案:

答案 0 :(得分:0)

我找到了一种解决方法,将getName设置为WithName.TypeNamet => t.GetType().Name,但现在我面临着映射问题:)

但是,我仍然不知道为什么这会解决StackOverflowException。如果有人知道,我会给他一个饼干。

修改 我和我的同事一起审核了它并找到了这个解决方案Registration by convention and interception causes ResolutionFailedException

所以我们添加一个新的Type过滤器

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

并将配置更改为WCF Factory,如下所示

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