web-dev-qa-db-ja.com

.NET Core 2.1のAOPを使用したロギング

.NET Core 2.1ソリューションのロギングにAOPを実装したい。私はこれまでこれまで使用したことがなく、オンラインで探していましたが、Core 2でこれを使用している人々の例を見ることができません。

たとえば、AOPに使用するパッケージと、開始するためのサンプルコードはありますか?組み込みのDIと.netコアを使用しているので、その部分について心配する必要はありません。

6
user2661305

Microsoft DIはインターセプターやデコレーターなどの高度なシナリオを提供していません(Microsoft DIを使用するデコレーターの回避策があります: https://medium.com/@willie.tetlow/net-core-dependency-injection-decorator- workaround-664cd3ec1246 )。

Autofac( https://autofaccn.readthedocs.io/en/latest/advanced/interceptors.html )または動的プロキシを使用したシンプルインジェクターを使用して、AOPを実装できます。両方とも本当に良いドキュメントを持っています。シンプルなインジェクターは、その設計ルールのため、傍受用のすぐに使えるソリューションはありませんが、拡張機能を追加できます( http://simpleinjector.readthedocs.io/en/latest/aop.html )。

これは、公式のSIドキュメントの基本的なAOPシナリオです:( http://simpleinjector.readthedocs.io/en/latest/InterceptionExtensions.html ):

//Add registration to the composition root
container.InterceptWith<MonitoringInterceptor>(serviceType => serviceType.Name.EndsWith("Repository"));`

// Here is an example of an interceptor implementation.
// NOTE: Interceptors must implement the IInterceptor interface:
private class MonitoringInterceptor : IInterceptor {
    private readonly ILogger logger;

  public MonitoringInterceptor(ILogger logger) {
        this.logger = logger;
    }

    public void Intercept(IInvocation invocation) {
        var watch = Stopwatch.StartNew();

        // Calls the decorated instance.
        invocation.Proceed();

        var decoratedType = invocation.InvocationTarget.GetType();

        this.logger.Log(string.Format("{0} executed in {1} ms.",
            decoratedType.Name, watch.ElapsedMilliseconds));
    }
}
3
aseaSharp

免責事項:私はこのソリューションのプロデューサーです

Microsoftは、Net Coreの箱から出してすぐにAOPソリューションを提供しますしません。しかし、私は役立つかもしれないサードパーティのプロジェクトを作成しました。 Net Coreと直接連携し、アプリケーションのServiceCollection登録を介してプラグインします。

Microsoftが提供するのは、クラスのプロキシオブジェクトを作成するために使用できるSystem.Runtime.DispatchProxyというライブラリです。ただし、このプロキシはそれ自体では特に有用または機能が豊富ではなく、Castle Proxy(よく知られているダイナミックプロキシライブラリ)と同じレベルにあるものを取得するには多くの追加コードが必要になります

そのことを念頭に置いて、DispatchProxyをコードにラップするライブラリを作成しました。これにより、アプリケーションの起動時にServiceCollection構成中に簡単に挿入できます。その秘訣は、属性を作成する方法と、メソッドに適用できるペアのインターセプターを用意することです。その後、属性はプロキシラッピング中に読み取られ、関連するインターセプターが呼び出されます。

これはインターセプター属性の例です

public class ConsoleLogAttribute : MethodInterceptorAttribute
{
}

これはInterceptorクラスの例です

public class ConsoleLogInterceptor : MethodInterceptor
{
    public override void BeforeInvoke(IInterceptionContext interceptionContext)
    {
        Console.WriteLine($"Method executing: {interceptionContext.CurrentMethod.Name}");
    }

    public override void AfterInvoke(IInterceptionContext interceptionContext, object methodResult)
    {
        Console.WriteLine($"Method executed: {interceptionContext.CurrentMethod.Name}");
    }
}

これはあなたの方法に適用される方法です

[ConsoleLog]
public void TestMethod()
{
}

そして最後に、これがServiceCollection構成に追加される方法です(プロキシするクラスが[TestClass]と呼ばれていると仮定します)。

public void ConfigureServices(IServiceCollection services)
{
    // Configure Simple Proxy
    services.EnableSimpleProxy(p => p.AddInterceptor<ConsoleLogAttribute, ConsoleLogInterceptor>());

    // Configure your services using the Extension Methods
    services.AddTransientWithProxy<ITestClass, TestClass>();
}

このGitHubプロジェクトを見てください: https://github.com/f135ta/SimpleProxy

0
Robert Perry