6

私が達成しようとしているのは、Castle Windsor インターセプターを使用した属性による AOP です。私はいくつかの成功を収めましたが、クラス レベルとメソッド レベルの側面に問題がありました。

  • クラス レベルの属性のみを使用すると、すべてのメソッドがインターセプトされます。
  • メソッド レベルの属性のみを使用すると、それらのメソッドはインターセプトされます。
  • クラス レベルの属性とメソッド レベルの属性を追加すると、属性が指定されたメソッドで両方のインターセプトが発生しますが、属性が指定されていないメソッドはインターセプトされません。

したがって、次のコンポーネントが与えられます。

public interface IMyComponent
{
    void ShouldBeInterceptedByStopWatch_AND_ExceptionLogger();
    void ShouldBeInterceptedByExceptionLogger();
}

[LogExceptionAspect]
public class MyComponent : IMyComponent
{
    [StopwatchAspect]
    public void ShouldBeInterceptedByStopWatch_AND_ExceptionLogger()
    {
        for (var i = 0; i < 2; i++) Thread.Sleep(1000);
    }

    public void ShouldBeInterceptedByExceptionLogger()
    {
        throw new NotImplementedException();
    }
}

ロガーの側面が傍受されることを期待しますShouldBeInterceptedByExceptionLogger()が、他のメソッドからストップウォッチの側面を削除するか、クラスからロガーの側面を削除してShouldBeInterceptedByExceptionLogger(). しかし、ShouldBeInterceptedByStopWatch_AND_ExceptionLogger()両方によって傍受されます。

サンプル アプリケーション全体は、https://bitbucket.org/jayala/juggernet-aopにあります。

基本的にIContributeComponentModelConstruction、クラスレベルでアスペクトが見つかった場合はインターセプターを追加する機能を登録する機能を使用するか、メソッドレベルでアスペクトが見つかった場合はインターセプター + メソッドフックを追加します。

これは、コンテナをブートストラップする方法です。

        var container = new WindsorContainer()
            .AddFacility<LogExceptionAspectFacility>()
            .AddFacility<StopwatchAspectFacility>()
            .Register(Component
                .For<IMyComponent>()
                .ImplementedBy<MyComponent>()
                .LifeStyle.Transient);

施設が行っているのは、このようなインターセプターとモデル コントリビューターの登録です。

public abstract class BaseAspectFacility<TAspectAttribute, TAspectInterceptor> : AbstractFacility
    where TAspectAttribute : Attribute
    where TAspectInterceptor : IInterceptor
{
    protected override void Init()
    {
        var interceptorName = Guid.NewGuid().ToString();
        Kernel.Register(Component.For<IInterceptor>()
                                 .Named(interceptorName)
                                 .ImplementedBy<TAspectInterceptor>()
                                 .LifeStyle.Singleton);
        var contributor = new ContributeAspectToModel<TAspectAttribute>(interceptorName);
        Kernel.ComponentModelBuilder.AddContributor(contributor);
    }
}
4

0 に答える 0