小白开学Asp.Net Core《四》

                              —— 使用AspectCore-Framework

 

一、AspectCore-Framework


 说AspectCore-Framework不得不先谈谈的AOP,

  AOP:在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程
<https://baike.baidu.com/item/%E9%9D%A2%E5%90%91%E5%88%87%E9%9D%A2%E7%BC%96%E7%A8%8B/6016335>
,通过预编译 <https://baike.baidu.com/item/%E9%A2%84%E7%BC%96%E8%AF%91/3191547>
方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP <https://baike.baidu.com/item/OOP>
的延续,是软件开发中的一个热点,是函数式编程
<https://baike.baidu.com/item/%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B/4035031>
的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度
<https://baike.baidu.com/item/%E8%80%A6%E5%90%88%E5%BA%A6/2603938>
降低,提高程序的可重用性,同时提高了开发的效率。(来自于百度百科)

  AspectCore-Framework 的具体介绍就不在这里造轮子了,下面列出几遍大佬们写的文章。

* 国内开源社区巨作AspectCore-Framework入门(码农阿宇)
<https://www.cnblogs.com/CoderAyu/p/9906349.html>
* AOP组件ASPectCore简单使用(YanBigFeg)
<https://www.cnblogs.com/yanbigfeg/p/9210158.html>
* AspectCore中的IoC容器和依赖注入
<https://github.com/dotnetcore/AspectCore-Framework/blob/master/docs/injector.md>
二、使用

* Nuget 安装 Aspectcore 及相关组件
       

   具体结合Redis来说明:

  Redis采用的是CSRedis

* Nuget CsRedis 及相关组件的安装
 

 下面就直接贴代码了

*   分布式Redis缓存 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(); } }
* Aspectcore Framwork 动态代理Redis [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); } } } }
* CSRedis 服务注册 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) //单机模式 redisClient = new
CSRedisClient(redisConnectionStrings[0]); else //集群模式 redisClient = new
CSRedisClient(NodeRule:null, connectionStrings: redisConnectionStrings); //初始化
RedisHelper RedisHelper.Initialization(redisClient); //注册mvc分布式缓存
services.AddSingleton<IDistributedCache>(new
Microsoft.Extensions.Caching.Redis.CSRedisCache(RedisHelper.Instance));return
services; }
* .Net Core Startup.cs 中注册服务 var redisConnectionString =
Configuration.GetConnectionString("Redis"); //启用Redis
services.UseCsRedisClient(redisConnectionString);return
AspectCoreContainer.BuildServiceProvider(services);//接入AspectCore.Injector
* 具体使用
* 简单的直接在Controller中使用 
            

*
*  在服务中使用
         

 

三、补充说明

  1、Redis 客户端安装本文默认都已安装

       2、一定要在Startup.cs 的 ConfigureServices 方法中进行服务的注册,并使用 return
AspectCoreContainer.BuildServiceProvider(services); 让AspectCore 接管,不是Aspectcore
是拦截不了的

       3、按照Aspectcore 的官方文档来说,需要加特性的方法必须是虚方法,也就是必须加virtual 修饰。不然不会被调用

       4、本文只是用Redis缓存来说名使用AOP(Aspectcore Framwork)的一方面,并不是说只能用于 Redis ,其他的(如
日志记录等)都可以使用的

       5、代码源码全部在Github上

 

(本人坚信:学习是由浅到深的过程,先打基础)

    不喜勿喷!谢谢!

  GitHub地址: https://github.com/AjuPrince/Aju.Carefree
<https://github.com/AjuPrince/Aju.Carefree>


友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信