Unity拦截使用自动布线

时间:2012-12-10 15:12:05

标签: asp.net-mvc unity-container aop interceptor

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

1 个答案:

答案 0 :(得分:1)

我的回答迟到了,但也许有人会觉得这很有用。

  • 如果我正确理解了问题,您需要将一个匹配规则应用于多个程序集。对于这类任务,您可以使用AssemblyMatchingRuleMSDN)。

    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