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

私は答えに遅れていますが、誰かがこれが役に立つと思うかもしれません。

  • 問題を正しく理解した場合は、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


詳細については、このリンクを確認してください-ポリシーインジェクションMSDN

于 2013-08-02T07:33:12.323 に答える