1

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

1 回答 1

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.


有关其他信息,请查看此链接 -策略注入 MSDN

于 2013-08-02T07:33:12.323 回答