小白開(kāi)學(xué)Asp.Net Core《四》
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? —— 使用AspectCore-Framework
?
一、AspectCore-Framework
說(shuō)AspectCore-Framework不得不先談?wù)劦腁OP,
AOP:在軟件業(yè),AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過(guò)預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。AOP是OOP的延續(xù),是軟件開(kāi)發(fā)中的一個(gè)熱點(diǎn),是函數(shù)式編程的一種衍生范型。利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開(kāi)發(fā)的效率。(來(lái)自于百度百科)
? AspectCore-Framework 的具體介紹就不在這里造輪子了,下面列出幾遍大佬們寫的文章。
二、使用
? ? ? ?
? 具體結(jié)合Redis來(lái)說(shuō)明:
Redis采用的是CSRedis
?下面就直接貼代碼了
public class DistributedCacheManager { private static IDistributedCache Instance => AspectCoreContainer.Resolve<IDistributedCache>(); public static string Get(string key) { if (RedisHelper.Exists(key)) { return RedisHelper.Get(key); } return null; } public static async Task<string> GetAsync(string key) { if (await RedisHelper.ExistsAsync(key)) { var content = await RedisHelper.GetAsync(key); return content; } return null; } public static T Get<T>(string key) { var value = Get(key); if (!string.IsNullOrEmpty(value)) return JsonConvertor.Deserialize<T>(value); return default(T); } public static async Task<T> GetAsync<T>(string key) { var value = await GetAsync(key); if (!string.IsNullOrEmpty(value)) { return JsonConvertor.Deserialize<T>(value); } return default(T); } public static void Set(string key, object data, int expiredSeconds) { RedisHelper.Set(key, JsonConvertor.Serialize(data), expiredSeconds); } public static async Task<bool> SetAsync(string key, object data, int expiredSeconds) { return await RedisHelper.SetAsync(key, JsonConvertor.Serialize(data), expiredSeconds); } public static void Remove(string key) => Instance.Remove(key); public static async Task RemoveAsync(string key) => await Instance.RemoveAsync(key); public static void Refresh(string key) => Instance.Refresh(key); public static async Task RefreshAsync(string key) => await Instance.RefreshAsync(key); public static void Clear() { throw new NotImplementedException(); } }
[AttributeUsage(AttributeTargets.Method)] public class RedisCacheAttribute : AbstractInterceptorAttribute { public int Expiration { get; set; } = 10 * 60; public string CacheKey { get; set; } = null; public override async Task Invoke(AspectContext context, AspectDelegate next) { var parameters = context.ServiceMethod.GetParameters(); if (parameters.Any(it => it.IsIn || it.IsOut)) await next(context); else { var key = string.IsNullOrEmpty(CacheKey) ? new CacheKey(context.ServiceMethod, parameters, context.Parameters).GetRedisCacheKey() : CacheKey; var value = await DistributedCacheManager.GetAsync(key); if (value != null) { if (context.ServiceMethod.IsReturnTask()) { dynamic result = JsonConvert.DeserializeObject(value, context.ServiceMethod.ReturnType.GenericTypeArguments[0]); context.ReturnValue = Task.FromResult(result); } else context.ReturnValue = JsonConvert.DeserializeObject(value, context.ServiceMethod.ReturnType); } else { await context.Invoke(next); dynamic returnValue = context.ReturnValue; if (context.ServiceMethod.IsReturnTask()) returnValue = returnValue.Result; await DistributedCacheManager.SetAsync(key, returnValue, Expiration); } } } }
public static IServiceCollection UseCsRedisClient(this IServiceCollection services, params string[] redisConnectionStrings) { if (services == null) throw new ArgumentNullException(nameof(services)); if (redisConnectionStrings == null || redisConnectionStrings.Length == 0) throw new ArgumentNullException(nameof(redisConnectionStrings)); CSRedisClient redisClient; if (redisConnectionStrings.Length == 1) //單機(jī)模式 redisClient = new CSRedisClient(redisConnectionStrings[0]); else //集群模式 redisClient = new CSRedisClient(NodeRule: null, connectionStrings: redisConnectionStrings); //初始化 RedisHelper RedisHelper.Initialization(redisClient); //注冊(cè)mvc分布式緩存 services.AddSingleton<IDistributedCache>(new Microsoft.Extensions.Caching.Redis.CSRedisCache(RedisHelper.Instance)); return services; }
var redisConnectionString = Configuration.GetConnectionString("Redis"); //啟用Redis services.UseCsRedisClient(redisConnectionString); return AspectCoreContainer.BuildServiceProvider(services);//接入AspectCore.Injector
? ? ? ? ? ??
? ? ? ? ?
?
三、補(bǔ)充說(shuō)明
1、Redis 客戶端安裝本文默認(rèn)都已安裝
? ? ? ?2、一定要在Startup.cs 的 ConfigureServices 方法中進(jìn)行服務(wù)的注冊(cè),并使用?return AspectCoreContainer.BuildServiceProvider(services); 讓AspectCore 接管,不是Aspectcore 是攔截不了的
? ? ? ?3、按照Aspectcore 的官方文檔來(lái)說(shuō),需要加特性的方法必須是虛方法,也就是必須加virtual 修飾。不然不會(huì)被調(diào)用
? ? ? ?4、本文只是用Redis緩存來(lái)說(shuō)名使用AOP(Aspectcore Framwork)的一方面,并不是說(shuō)只能用于 Redis ,其他的(如 日志記錄等)都可以使用的
? ? ? ?5、代碼源碼全部在Github上
Github地址:https://github.com/AjuPrince/Aju.Carefree
總結(jié)
以上是生活随笔為你收集整理的小白开学Asp.Net Core《四》 —— 使用AspectCore-Framework的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。