web-dev-qa-db-fra.com

Journalisation à l'aide d'AOP dans .NET Core 2.1

Je souhaite implémenter AOP pour la journalisation dans ma solution .NET Core 2.1. Je ne l'ai jamais utilisé auparavant et j'ai cherché en ligne et je ne peux pas voir d'exemples de personnes l'utilisant avec Core 2. Est-ce que quelqu'un sait comment j'y arriverais?

Par exemple, quels packages utiliser pour AOP et avoir un exemple de code pour commencer? J'utilise la DI intégrée avec le noyau .net, donc je n'ai pas besoin de m'inquiéter pour cette partie.

6
user2661305

Microsoft DI n'offre pas de scénarios avancés tels que les intercepteurs ou les décorateurs (il existe une solution de contournement pour les décorateurs utilisant Microsoft DI: https://medium.com/@willie.tetlow/net-core-dependency-injection-decorator-) solution de contournement-664cd3ec1246 ).

Vous pouvez implémenter AOP en utilisant Autofac ( https://autofaccn.readthedocs.io/en/latest/advanced/interceptors.html ) ou un injecteur simple avec proxy dynamique. Les deux ont une très bonne documentation. L'injecteur simple n'a pas de solution prête à l'emploi pour l'interception en raison de leurs règles de conception, mais vous pouvez lui ajouter une extension ( http://simpleinjector.readthedocs.io/en/latest/aop.html ).

Voici un scénario AOP de base de la documentation officielle SI: ( 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

Avertissement: je suis le producteur de cette solution

Microsoft ne fournit pas une solution AOP prête à l'emploi pour Net Core. Cependant, j'ai produit un projet tiers qui peut aider. Il fonctionne directement avec Net Core et se connecte via l'enregistrement ServiceCollection dans votre application.

Ce que Microsoft fournit est une bibliothèque appelée System.Runtime.DispatchProxy qui peut être utilisée pour créer des objets proxy pour vos classes. Cependant, ce proxy n'est pas particulièrement utile ou riche en fonctionnalités à lui seul et nécessiterait beaucoup de code supplémentaire pour obtenir quelque chose qui soit au même niveau que Castle Proxy (la bibliothèque Dynamic Proxy bien connue)

Dans cet esprit, j'ai créé une bibliothèque qui encapsule le DispatchProxy dans du code qui peut être facilement injecté lors de la configuration de ServiceCollection au démarrage de l'application. L'astuce consiste à avoir un moyen de créer des attributs ET un intercepteur couplé qui peut être appliqué à vos méthodes. L'attribut est ensuite lu lors de l'encapsulage du proxy et l'intercepteur correspondant est appelé.

Ceci est un exemple d'attribut d'intercepteur

public class ConsoleLogAttribute : MethodInterceptorAttribute
{
}

Ceci est un exemple de classe 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}");
    }
}

Voici comment cela serait appliqué à votre méthode

[ConsoleLog]
public void TestMethod()
{
}

Et enfin, voici comment il serait ajouté à votre configuration ServiceCollection (en supposant que la classe que vous vouliez proxy était appelée [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>();
}

Jetez un œil à ce projet GitHub: https://github.com/f135ta/SimpleProxy

0
Robert Perry