什麼是AspectCore Project ?

來源:互聯網
上載者:User

什麼是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>();});

    作用於特定ServiceMethod的全域攔截器,下面的代碼示範了作用於帶有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來使得ServiceMethod不被代理:

    [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);    }}
  • 使用AutofacAspectCore。AspectCore原生支援整合Autofac,我們需要安裝下面兩個nuget packages:

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

    AspectCore提供RegisterAspectCore擴充方法在Autofac的Container中註冊動態代理需要的服務,並提供AsInterfacesProxyAsClassProxy擴充方法啟用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());}

有問題反饋

如果您有任何問題,請提交 Issue 給我們。
AspectCore Project 項目地址:

最後。。。

正在找工作,歡迎推薦.NET/.NET Core後端開發職位,座標上海,可私信或Email。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.