小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

ASP.NET Core 3.0 使用AspectCore-Framework實(shí)現(xiàn)AOP

 路人甲Java 2020-05-10

AspectCore是適用于Asp.Net Core 平臺(tái)的輕量級(jí)Aop(Aspect-oriented programming)解決方案,它更好的遵循Asp.Net Core的模塊化開發(fā)理念,使用AspectCore可以更容易構(gòu)建低耦合、易擴(kuò)展的Web應(yīng)用程序。

在使用過程中,由于相關(guān)文檔、博客還未更新到.Net Core 3.0,本文操作參考了使用.Net Core 3.0的EasyCaching,并對(duì)其中公用的方法進(jìn)行封裝簡(jiǎn)化。

安裝Aspectcore

此處配合微軟自家的DI實(shí)現(xiàn),安裝Nuget包AspectCore.Extensions.DependencyInjection,其中包含AspectCore.Core和Microsoft.Extensions.DependencyInjection兩個(gè)依賴。

Install-Package AspectCore.Extensions.DependencyInjection -Version 1.3.0

攔截器

  • 特性攔截器
    新建一個(gè)特性攔截器TestInterceptorAttribute,繼承AbstractInterceptorAttribute,并重寫Invoke方法,在方法中實(shí)現(xiàn)攔截相關(guān)業(yè)務(wù)。
public class TestInterceptorAttribute : AbstractInterceptorAttribute
{
    public override Task Invoke(AspectContext context, AspectDelegate next)
    {
        return context.Invoke(next);
    }
}
  • 全局?jǐn)r截器
    新建一個(gè)全局?jǐn)r截器TestInterceptor,繼承AbstractInterceptor,并重寫Invoke方法,在方法中實(shí)現(xiàn)攔截相關(guān)業(yè)務(wù)。
public class TestInterceptor : AbstractInterceptor
{
    public override Task Invoke(AspectContext context, AspectDelegate next)
    {
        return context.Invoke(next);
    }
}

注冊(cè)服務(wù)

以下注冊(cè)方式僅適用于asp.net core 3.0(目前只到3.0),已知在2.2版本中,需要在ConfigureServices方法中返回IServiceProvider,并且program.cs中也不再需要替換ServiceProviderFactory。
1.創(chuàng)建AspectCoreEctensions.cs擴(kuò)展IServiceCollection

public static class AspectCoreExtensions
{
	public static void ConfigAspectCore(this IServiceCollection services)
	{
        services.ConfigureDynamicProxy(config =>
		{
            //TestInterceptor攔截器類
            //攔截代理所有Service結(jié)尾的類
			config.Interceptors.AddTyped<TestInterceptor>(Predicates.ForService("*Service"));
		});
		services.BuildAspectInjectorProvider();
	}
}

2.在Startup.cs中注冊(cè)服務(wù)

public void ConfigureServices(IServiceCollection services)
{   
    services.ConfigAspectCore();
}

3.在Program.cs中替換ServiceProviderFactory

public static IHostBuilder CreateHostBuilder(string[] args) =>
	Host.CreateDefaultBuilder(args)
	.ConfigureWebHostDefaults(webBuilder =>
	{
		webBuilder.UseStartup<Startup>();
	}).UseServiceProviderFactory(new AspectCoreServiceProviderFactory());

被攔截方法編寫

  • 代理接口:在接口上標(biāo)注Attribute
public interface ITestService
{
	[TestInterceptor]
	void Test();
}
  • 代理類(方法):在方法上標(biāo)注Attribute,并且標(biāo)注virtual
public class TestService
{
    [TestInterceptor]
    public virtual void Test()
    {
        //業(yè)務(wù)代碼
    }
}

攔截器業(yè)務(wù)編寫

  • 執(zhí)行被攔截方法
private async Task<object> RunAndGetReturn()
{
	await Context.Invoke(Next);
	return Context.IsAsync()
		? await Context.UnwrapAsyncReturnValue()
		: Context.ReturnValue;
}
  • 攔截器中的依賴注入
[FromContainer]
private RedisClient RedisClient { get; set; }
  • 獲取被攔截方法的Attribute
private static readonly ConcurrentDictionary<MethodInfo, object[]>
					MethodAttributes = new ConcurrentDictionary<MethodInfo, object[]>();

public static T GetAttribute<T>(this AspectContext context) where T : Attribute
{
	MethodInfo method = context.ServiceMethod;
	var attributes = MethodAttributes.GetOrAdd(method, method.GetCustomAttributes(true));
	var attribute = attributes.FirstOrDefault(x => typeof(T).IsAssignableFrom(x.GetType()));
	if (attribute is T)
	{
		return (T)attribute;
	}
	return null;
}
  • 獲取被攔截方法返回值類型
public static Type GetReturnType(this AspectContext context)
{
	return context.IsAsync()
		? context.ServiceMethod.ReturnType.GetGenericArguments()First()
		: context.ServiceMethod.ReturnType;
}
  • 處理攔截器返回結(jié)果
private static readonly ConcurrentDictionary<Type, MethodInfo>
				   TypeofTaskResultMethod = new ConcurrentDictionary<Type, MethodInfo>();
public object ResultFactory(this AspectContext context,object result)
{
	var returnType = context.GetReturnType();

    //異步方法返回Task<T>類型結(jié)果
	if (context.IsAsync())
	{
		return TypeofTaskResultMethod
				.GetOrAdd(returnType, t => typeof(Task)
				.GetMethods()
				.First(p => p.Name == "FromResult" && p.ContainsGenericParameters)
				.MakeGenericMethod(returnType))
				.Invoke(null, new object[] { result });
	}
	else
	{
		return result;
	}
}

相關(guān)鏈接

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多