Asp.NetCore實現Aop,AspectCore實現Aop ...
dotnetcore實現Aop
Aop大家都不陌生,然而今天給大家不將講官方的filter,今天給大家分享一個輕量級的Aop解決方案(AspectCore)
什麼是AspectCore
AspectCore是一個面向切麵編程,基於.NetCore和.NetFramwork的擴平臺框架,對方法攔截器、依賴項註入集成、web應用程式、數據驗證等提供核心支持。
AspectCore基本特性
-
提供抽象的Aop介面,基於該介面可以輕鬆的使用自己的代理類實現替換預設的實現.
-
框架不包含IoC,也不依賴具體IoC實現,可以使用Asp.Net Core的內置依賴註入或者任何相容Asp.Net Core的第三方Ioc來繼承AspectCore到Asp.NetCore應用中
-
高性能的非同步攔截系統
-
靈活的配置系統
-
基於service的而非基於實現類的切麵構造
-
支持擴平臺的Asp.Net Core環境
使用AspectCore
從NuGet中安裝AspectCore
AspectCore.Extensions.DependencyInjection
package
PM> Install-package AspectCore.Extensions.DependencyInjection
下麵我創建了一個Api應用程式.
NuGet安裝
AspectCore.Configuration
package
PM> Install-package AspectCore.Configuration
下麵我新建了一個攔截器 CustomInterceptorAttribute,繼承AbstractInterceptorAttribute(一般情況下繼承他即可),他實現IInterceptor介面AspectCore預設實現了基於Attribute
的攔截器配置。
/// <summary>
/// 自定義攔截器
/// </summary>
public class CustomInterceptorAttribute : AbstractInterceptorAttribute
{
/// <summary>
/// 實現抽象方法
/// </summary>
/// <param name="context"></param>
/// <param name="next"></param>
public override async Task Invoke(AspectContext context, AspectDelegate next)
{
try
{
Console.WriteLine("執行之前");
await next(context);//執行被攔截的方法
}
catch (Exception)
{
Console.WriteLine("被攔截的方法出現異常");
throw;
}
finally
{
Console.WriteLine("執行之後");
}
}
}
定義ICustomService
介面和它的實現類CustomService
:
public interface ICustomService
{
DateTime GetDateTime();
}
public class CustomService : ICustomService
{
public DateTime GetDateTime()
{
return DateTime.Now;
}
}
在ValuesController註入ICustomService
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly ICustomService _icustomserveice;
public ValuesController(ICustomService icustomService) {
this._icustomserveice = icustomService;
}
// GET api/values
[HttpGet]
public DateTime Get()
{
return _icustomserveice.GetDateTime();
}
}
註冊ICustomService,並創建代理容器
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddTransient<ICustomService,CustomService>();
services.AddMvc();
//全局攔截器。使用AddDynamicProxy(Action<IAspectConfiguration>)的重載方法,其中IAspectConfiguration提供Interceptors註冊全局攔截器:
services.ConfigureDynamicProxy(config=> {
config.Interceptors.AddTyped<CustomInterceptorAttribute>();
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
return services.BuildAspectInjectorProvider();
}
作為服務的全局攔截器。在ConfigureServices
中添加:
services.AddTransient<CustomInterceptorAttribute>(provider => new CustomInterceptorAttribute());
作用於特定Service
或Method
的全局攔截器,下麵的代碼演示了作用於帶有Service
尾碼的類的全局攔截器:
services.ConfigureDynamicProxy(config =>
{
config.Interceptors.AddTyped<CustomInterceptorAttribute>(method => method.DeclaringType.Name.EndsWith("Service"));
});
通配符攔截器,匹配尾碼為Service
services.ConfigureDynamicProxy(config =>
{
config.Interceptors.AddTyped<CustomInterceptorAttribute>(Predicates.ForService("*Service"));
});
在AspectCore中提供NonAspectAttribute
來使得Service
或Method
不被代理:
[NonAspect]
DateTime GetDate();
全局配置忽略條件
services.ConfigureDynamicProxy(config =>
{
//Namespace命名空間下的Service不會被代理
config.NonAspectPredicates.AddNamespace("Namespace");
//最後一級為Namespace的命名空間下的Service不會被代理
config.NonAspectPredicates.AddNamespace("*.Namespace");
//ICustomService介面不會被代理
config.NonAspectPredicates.AddService("ICustomService");
//尾碼為Service的介面和類不會被代理
config.NonAspectPredicates.AddService("*Service");
//命名為Method的方法不會被代理
config.NonAspectPredicates.AddMethod("Method");
//尾碼為Method的方法不會被代理
config.NonAspectPredicates.AddMethod("*Method");
});
AspectCore: [https://github.com/dotnetcore/AspectCore-Framework]
測試項目地址: [https://github.com/fhcodegit/DotNetAspectCore/tree/master]