在 WCF 中使用 Unity 拦截器获取 System.StackOverflowException

Getting System.StackOverflowException with Unity Interceptor in WCF

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

仅供参考:我检查我是否有 circular dependancy or a 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);

    }
} 

我的拦截行为

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.WhosebugException' occurred in mscorlib.dll 吗?

痕迹

如果您需要更多信息,请随时询问。

感谢帮助


更新

如果我删除拦截器,我当然不会再有异常了:

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

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

但是我仍然不知道为什么这会解决 WhosebugException。谁知道我就给他一块饼干

编辑 我们和我的同事一起审查了它并找到了这个解决方案 Registration by convention and interception causes ResolutionFailedException

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

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 工厂

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