我使用HadlerAttribute和ICallHandler实例进行Unity拦截。为了让它工作,我所要做的就是用[Trace]属性装饰类,拦截器工作得很好。
[Trace]
public interface IPersonService
{
string GetPerson();
}
但是我希望在几个程序集中对所有方法进行拦截。所以我使用Unity AutoRegistration按如下方式设置我的容器:
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
//container.AddNewExtension<UnityInterfaceInterceptionRegisterer>();
container.
ConfigureAutoRegistration().
ExcludeSystemAssemblies().
LoadAssemblyFrom(typeof(PersonService).Assembly.Location).
Include(If.ImplementsITypeName, Then.Register()).
ApplyAutoRegistration();
return container;
}
效果很好,除非我按照这篇文章尝试设置全局注册: http://unity.codeplex.com/discussions/281022
我有一个UnityContainerExtension配置如下,其中MVC4Unity是我的DLL:
public class UnityInterfaceInterceptionRegisterer : UnityContainerExtension
{
protected override void Initialize()
{
base.Container.AddNewExtension<Interception>();
base.Container.Configure<Interception>().
AddPolicy("LoggingPolicy").
AddMatchingRule<AssemblyMatchingRule>
(new InjectionConstructor("MVC4Unity")).
AddCallHandler(new TraceCallHandler());
base.Context.Registering += new EventHandler<RegisterEventArgs>(this.OnRegister);
}
private void OnRegister(object sender, RegisterEventArgs e)
{
IUnityContainer container = sender as IUnityContainer;
if (e != null && e.TypeFrom != null && e.TypeFrom.IsInterface)
{
container.Configure<Interception>()
.SetInterceptorFor(e.TypeFrom, e.Name, new InterfaceInterceptor());
}
}
}
不幸的是,当它进入OnRegister方法时,它总是抛出一个StackOverflowException(!)。
接下来的问题是,有没有人使用Unity实现程序集甚至名称空间宽拦截,这是要走的路吗?
[编辑]
似乎无论我在下面的AddMatchingRule行添加什么,都会为所有包含的程序集调用OnRegister处理程序! (例如,甚至是Microsoft。*命名空间程序集!)
base.Container.AddNewExtension<Interception>();
base.Container.Configure<Interception>().
AddPolicy("LoggingPolicy").
// see what other types of matchings rules there are!
AddMatchingRule<NamespaceMatchingRule>
(new InjectionConstructor("MVC4Unity.*")).
AddCallHandler(new TraceCallHandler());
base.Context.Registering += new EventHandler<RegisterEventArgs>(this.OnRegister);
答案 0 :(得分:1)
我的回答迟到了,但也许有人会觉得这很有用。
如果我正确理解了问题,您需要将一个匹配规则应用于多个程序集。对于这类任务,您可以使用AssemblyMatchingRule
(MSDN)。
container.Configure<Interception>()
.AddPolicy("logging")
.AddMatchingRule<AssemblyMatchingRule>(
new InjectionConstructor(
new InjectionParameter("YourAssemblyName")))
.AddCallHandler<LoggingCallHandler>(
new ContainerControlledLifetimeManager(),
new InjectionConstructor(), new InjectionProperty("Order", 1));
在您的上一个代码段中,我认为您需要在命名空间末尾删除点星号,以便将MVC4Unity
命名空间添加到NamespaceMatchingRule
。
有关其他信息,请查看此链接 - Policy Injection MSDN