淺談AspectCore_實用技巧

零下一度
發布: 2017-06-15 13:49:50
原創
2345 人瀏覽過

這篇文章主要介紹了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 專案。


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提供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.DependencyInjection
PM> 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());
}
登入後複製

以上是淺談AspectCore_實用技巧的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板