我使用 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);