在 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.TypeName
或 t => 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>()
});
我正在将来自 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.TypeName
或 t => 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>()
});