淺談AspectCore_實用技巧

來源:互聯網
上載者:User
這篇文章主要介紹了Asp.Net Core輕量級Aop解決方案:AspectCore,需要的朋友可以參考下

什麼是AspectCore Project ?

AspectCore Project 是適用於Asp.Net Core 平台的輕量級 Aop(Aspect-oriented programming) 解決方案,它更好的遵循Asp.Net Core的模組化開發理念,使用AspectCore可以更容易構建低耦合、易擴充的Web應用程式。AspectCore使用Emit實現高效的動態代理從而不依賴任何第三方Aop庫。

開使使用AspectCore

啟動 Visual Studio。從 File 菜單, 選擇 New > Project。選擇 ASP.NET Core Web Application 項目模版,建立新的 ASP.NET Core Web Application 項目。

  • 從 Nuget 安裝 AspectCore.Extensions.DependencyInjection package:

  • PM> Install-Package AspectCore.Extensions.DependencyInjection

  • 在一般情況下可以使用抽象的InterceptorAttribute自訂屬性類別,它實現IInterceptor介面。AspectCore預設實現了基於Attribute的攔截器配置。我們的自訂攔截器看起來像下面這樣:


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");    }   } }

定義ICustomService介面和它的實作類別CustomService:


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

在HomeController中注入ICustomService:


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

註冊ICustomService,接著,在ConfigureServices中配置建立代理類型的容器:


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

攔截器配置。首先安裝AspectCore.Extensions.Configuration package:


PM> Install-Package AspectCore.Extensions.Configuration

全域攔截器。使用AddAspectCore(Action<AspectCoreOptions>)的重載方法,其中AspectCoreOptions提供InterceptorFactories註冊全域攔截器:


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

帶構造器參數的全域攔截器,在CustomInterceptorAttribute中添加帶參數的構造器:


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");    }  }}

修改全域攔截器註冊:


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

作為服務的全域攔截器。在ConfigureServices中添加:


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

修改全域攔截器註冊:


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

作用於特定Service或Method的全域攔截器,下面的代碼示範了作用於帶有Service尾碼的類的全域攔截器:


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

使用萬用字元的特定全域攔截器:


services.AddAspectCore(config =>{  config.InterceptorFactories.AddTyped<CustomInterceptorAttribute>(PredicateFactory.ForService("*Service"));});

在AspectCore中提供NonAspectAttribute來使得Service或Method不被代理:


[NonAspect]public interface ICustomService{  void Call();}

同時支援全域忽略配置,亦支援萬用字元:


 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"); });

攔截器中的依賴注入。在攔截器中支援屬性注入,構造器注入和服務定位器模式。
屬性注入,在攔截器中擁有public get and set許可權的屬性標記[AspectCore.Abstractions.FromServices](區別於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);  }}

構造器注入需要使攔截器作為Service,除全域攔截器外,仍可使用ServiceInterceptor使攔截器從DI中啟用:


public interface ICustomService{  [ServiceInterceptor(typeof(CustomInterceptorAttribute))]  void Call();}

服務定位器模式。攔截器上下文AspectContext可以擷取當前Scoped的ServiceProvider:


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);  }}

使用Autofac和AspectCore。AspectCore原生支援整合Autofac,我們需要安裝下面兩個nuget packages:


PM> Install-Package Autofac.Extensions.DependencyInjectionPM> Install-Package AspectCore.Extensions.Autofac

AspectCore提供RegisterAspectCore擴充方法在Autofac的Container中註冊動態代理需要的服務,並提供AsInterfacesProxy和AsClassProxy擴充方法啟用interface和class的代理。修改ConfigureServices方法為:


public IServiceProvider ConfigureServices(IServiceCollection services){  services.AddMvc();  var container = new ContainerBuilder();  container.RegisterAspectCore();  container.Populate(services);  container.RegisterType<CustomService>().As<ICustomService>().InstancePerDependency().AsInterfacesProxy();  return new AutofacServiceProvider(container.Build());}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.