Heim  >  Artikel  >  Backend-Entwicklung  >  Eine kurze Diskussion über AspectCore_Practical skills

Eine kurze Diskussion über AspectCore_Practical skills

零下一度
零下一度Original
2017-06-15 13:49:502270Durchsuche

In diesem Artikel wird hauptsächlich die leichte Aop-Lösung von Asp.Net Core vorgestellt: AspectCore. Freunde, die sie benötigen, können darauf verweisen

Was ist das AspectCore-Projekt?

AspectCore Project ist eine leichtgewichtige Aop-Lösung (Aspektorientierte Programmierung), die sich besser an das modulare Entwicklungskonzept von Asp.Net Core anpasst und einfacher mit geringer Kopplung erstellt werden kann. leicht skalierbare Webanwendungen. AspectCore verwendet Emit, um einen effizienten dynamischen Proxy zu implementieren, ohne auf eine Aop-Bibliothek eines Drittanbieters angewiesen zu sein.

Visual Studio mit AspectCore starten

. Wählen Sie im Menü „Datei“ die Option „Neu“ > „Projekt“. Wählen Sie die ASP.NET Core-Webanwendungsprojektvorlage aus und erstellen Sie ein neues ASP.NET Core-Webanwendungsprojekt.

  • Installieren Sie das AspectCore.Extensions.DependencyInjection-Paket von Nuget:

  • PM> Install-Package AspectCore.Extensions.DependencyInjection

  • Im Allgemeinen können Sie die abstrakte benutzerdefinierte Attributklasse InterceptorAttribute verwenden, die die IInterceptorSchnittstelle implementiert. AspectCore implementiert standardmäßig die attributbasierte Interceptor-Konfiguration. Unser benutzerdefinierter Interceptor sieht so aus:


public class CustomInterceptorAttribute : InterceptorAttribute
{
  public async override Task Invoke(IAspectContext context, AspectDelegate next)
  {
    try
    {
      Console.WriteLine("Before service call");
      await next(context);
    }
    catch (Exception)
    {
      Console.WriteLine("Service threw an exception!");
      throw;
    }
    finally
    {
      Console.WriteLine("After service call");
    }
   }
 }

Definieren Sie die ICustomService-Schnittstelle und ihre Implementierungsklasse CustomService:


public interface ICustomService
{
  [CustomInterceptor]
  void Call();
}
public class CustomService : ICustomService
{
  public void Call()
  {
    Console.WriteLine("service calling...");
  }
}

Injizieren Sie ICustomService in HomeController:


public class HomeController : Controller
{
  private readonly ICustomService _service;
  public HomeController(ICustomService service)
  {
    _service = service;
  }
  public IActionResult Index()
  {
    _service.Call();
    return View();
  }
}

Registrieren Sie ICustomService und konfigurieren Sie dann den erstellten Proxy-Typ im ConfigureServices-Container:


public IServiceProvider ConfigureServices(IServiceCollection services)
{
  services.AddTransient<ICustomService, CustomService>();
  services.AddMvc();
  services.AddAspectCore();
  return services.BuildAspectCoreServiceProvider();
}

Interceptor-Konfiguration. Installieren Sie zunächst das AspectCore.Extensions.Configuration-Paket:


PM> Install-Package AspectCore.Extensions.Configuration

Global Interceptor. Verwenden Sie AddAspectCore(Actioncf55c8c03f0256412fce639ce72d0b5d) von , um die -Methode zu überladen, wobei AspectCoreOptions InterceptorFactories bereitstellt, um einen globalen Interceptor zu registrieren:


 services.AddAspectCore(config =>
 {
   config.InterceptorFactories.AddTyped<CustomInterceptorAttribute>();
 });

Globaler Interceptor mit Konstruktorparametern , fügen Sie einen Konstruktor mit Parametern in CustomInterceptorAttribute hinzu:


public class CustomInterceptorAttribute : InterceptorAttribute
{
  private readonly string _name;
  public CustomInterceptorAttribute(string name)
  {
    _name = name;
  }
  public async override Task Invoke(AspectContext context, AspectDelegate next)
  {
    try
    {
      Console.WriteLine("Before service call");
      await next(context);
    }
    catch (Exception)
    {
      Console.WriteLine("Service threw an exception!");
      throw;
    }
    finally
    {
      Console.WriteLine("After service call");
    }
  }
}

Ändern Sie die globale Interceptor-Registrierung:


services.AddAspectCore(config =>
{
   config.InterceptorFactories.AddTyped<CustomInterceptorAttribute>(args: new object[] { "custom" });
});

Fungiert als globaler Abfangjäger für den Dienst. Fügen Sie „ConfigureServices“ hinzu:


services.AddTransient<CustomInterceptorAttribute>(provider => new CustomInterceptorAttribute("service"));

Ändern Sie die globale Interceptor-Registrierung:


services.AddAspectCore(config =>
{
  config.InterceptorFactories.AddServiced<CustomInterceptorAttribute>();
});

, um auf bestimmte Globale zu reagieren Der folgende Code zeigt den globalen Interceptor, der auf Klassen mit dem Suffix „Service“ wirkt:


services.AddAspectCore(config =>
{
  config.InterceptorFactories.AddTyped<CustomInterceptorAttribute>(method => method.DeclaringType.Name.EndsWith("Service"));
});

Verwenden Sie den Platzhalter<. spezifischer globaler interceptor f>:


services.AddAspectCore(config =>
{
  config.InterceptorFactories.AddTyped<CustomInterceptorAttribute>(PredicateFactory.ForService("*Service"));
});
Stellen Sie NonAspectAttribute in AspectCore bereit, um zu verhindern, dass Dienst oder Methode als Proxy verwendet werden:


[NonAspect]
public interface ICustomService
{
  void Call();
}
Unterstützt auch globale Ignorierkonfiguration und Platzhalter:



 services.AddAspectCore(config =>
 {
   //App1命名空间下的Service不会被代理
   config.NonAspectOptions.AddNamespace("App1");
   //最后一级为App1的命名空间下的Service不会被代理
   config.NonAspectOptions.AddNamespace("*.App1");
   //ICustomService接口不会被代理
   config.NonAspectOptions.AddService("ICustomService");
   //后缀为Service的接口和类不会被代理
   config.NonAspectOptions.AddService("*Service");
   //命名为Query的方法不会被代理
   config.NonAspectOptions.AddMethod("Query");
   //后缀为Query的方法不会被代理
   config.NonAspectOptions.AddMethod("*Query");
 });

Abhängigkeitsinjektion im Interceptor. Unterstützt Eigenschaftsinjektion, Konstruktorinjektion und Service-Locator-Muster in Interceptoren. Attributinjektion, die Attributmarkierung [
] (anders als ) mit öffentlichen Get- und SetAspectCore.Abstractions.FromServices-Berechtigungen im Interceptor kann das Attribut automatisch injizieren, z. B.: Microsoft.AspNetCore.Mvc.FromServices


public class CustomInterceptorAttribute : InterceptorAttribute
{
  [AspectCore.Abstractions.FromServices]
  public ILogger<CustomInterceptorAttribute> Logger { get; set; }
  public override Task Invoke(AspectContext context, AspectDelegate next)
  {
    Logger.LogInformation("call interceptor");
    return next(context);
  }
}
Für die Konstruktorinjektion muss der Interceptor als Dienst verwendet werden. Zusätzlich zum globalen Interceptor kann der ServiceInterceptor weiterhin verwendet werden, um den Interceptor von DI aus zu aktivieren:


public interface ICustomService
{
  [ServiceInterceptor(typeof(CustomInterceptorAttribute))]
  void Call();
}
Service-Locator-Modus. Der Interceptor-Kontext AspectContext kann den aktuellen Scoped ServiceProvider abrufen:


public class CustomInterceptorAttribute : InterceptorAttribute
{
  public override Task Invoke(AspectContext context, AspectDelegate next)
  {
    var logger = context.ServiceProvider.GetService<ILogger<CustomInterceptorAttribute>>();
    logger.LogInformation("call interceptor");
    return next(context);
  }
}
Mit Autofac und AspectCore. AspectCore unterstützt nativ die Integration von Autofac. Wir müssen die folgenden zwei Nuget-Pakete installieren:


PM> Install-Package Autofac.Extensions.DependencyInjection
PM> Install-Package AspectCore.Extensions.Autofac
AspectCore bietet die RegisterAspectCore-Erweiterungsmethode, um die für dynamische Agenten erforderlichen Dienste in Autofac zu registrieren Container. Und stellen Sie die Erweiterungsmethoden AsInterfacesProxy und AsClassProxy bereit, um den Proxy von Schnittstelle und Klasse zu aktivieren. Ändern Sie die Methode „ConfigureServices“ wie folgt:


Das obige ist der detaillierte Inhalt vonEine kurze Diskussion über AspectCore_Practical skills. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn