小白开学Asp.Net Core 《四》
小白开学Asp.Net Core《四》
—— 使用AspectCore-Framework
一、AspectCore-Framework
说AspectCore-Framework不得不先谈谈的AOP,
AOP:在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。(来自于百度百科)
AspectCore-Framework 的具体介绍就不在这里造轮子了,下面列出几遍大佬们写的文章。
二、使用
- 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; } = * ; 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[]);
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 == )
throw new ArgumentNullException(nameof(redisConnectionStrings));
CSRedisClient redisClient;
if (redisConnectionStrings.Length == )
//单机模式
redisClient = new CSRedisClient(redisConnectionStrings[]);
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上
四、参考文章
https://github.com/VictorTzeng/Zxw.Framework.NetCore
(本人坚信:学习是由浅到深的过程,先打基础)
不喜勿喷!谢谢!
GitHub地址: https://github.com/AjuPrince/Aju.Carefree

小白开学Asp.Net Core 《四》的更多相关文章
- 小白开学Asp.Net Core 《九》
小白开学Asp.Net Core <九> — — 前端篇(不务正业) 在<小白开学Asp.Net Core 三>中使用了X-admin 2.x 和 Layui将管理后端的界面重 ...
- 小白开学Asp.Net Core 《五》
小白开学Asp.Net Core<五> —— 使用.Net Core MVC Filter 一.简介 今天在项目(https:/ ...
- 小白开学Asp.Net Core 《六》
小白开学Asp.Net Core <六> —— 探究.Net Core 跨平台的奥秘 1.写这篇文章的初衷 有好多朋友反馈看不懂我写的开源的一个练手项目(GitHub:https://gi ...
- 小白开学Asp.Net Core 《七》
小白开学Asp.Net Core <七> — — 探究中间件(MiddleWare) 1.何为中间件? 中间件是组装到应用程序管道中以处理请求和响应的家伙,管道中的每个组件都要满足以下两个 ...
- 小白开学Asp.Net Core《三》
小白开学Asp.Net Core<三> ——界面 我胡汉三再次又回来了(距离上篇时间有点长),今天抽时间将最近对框架采用的后台界面做个记录 1.先上图 (图一) (图二) 2.界面说明 后 ...
- 小白开学Asp.Net Core《二》(补)
小白开学Asp.Net Core<二>(补) ——数据仓储层(Repositroy).服务层(Service) -------------------------------------- ...
- 小白开学Asp.Net Core《二》
小白开学Asp.Net Core<二> ——数据仓储层(Repositroy) 一.历史现象 在后端开发中,数据库操作是最频繁的,每一个开发人员都会接触,甚至不少开发人员每天的工作就是与数 ...
- 小白开学Asp.Net Core 《十》
小白开学Asp.Net Core <十> — — Session.Cookie.Cache(老生常谈) 一.背景 在常谈Session和Cookie之前我们先来简单的了解下Http(可以说 ...
- 小白开学Asp.Net Core 《八》
小白开学Asp.Net Core <八> — — .Net Core 数据保护组件 1.背景 我在搞(https://github.com/AjuPrince/Aju.Carefree)这 ...
随机推荐
- 常用user agent
测试user agnet的网站: http://whatsmyuseragent.com/ Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) ...
- java程序设计第二课
抽象基类和接口 能够使用keywordabstact来创建抽象类,该抽象类不能被实例化 也能够使用keywordabstact来描写叙述一个尚未被详细实现的方法,该方法不能包括方法体 一个抽象方法仅仅 ...
- VC实现程序重启的做法
作者:朱金灿 来源:http://blog.csdn.net/clever101 很多时候系统有很多配置项,修改了配置项之后能有一个按钮实现系统重启.所谓重启就是杀死系统的当前进程,然后重新开一个新进 ...
- WPF 3D 平移模型+动画(桥梁检测系统)
原文:WPF 3D 平移模型+动画(桥梁检测系统) 关于WPF 3D,网上有很多旋转的例子,但是关于平移的例子并不是太多.本文并非WPF 3D扫盲篇,因此需要对WPF 3D有一定了解,至少知道View ...
- React HOC
在React官网文档学习React HOC,整个看了一遍还是云里雾里的,于是按照官网文档,自己动手实践一下.官网地址:React 高阶组件 定义:高阶组件就是一个函数,且该函数接受一个组件作为参数,并 ...
- 使用 NodeJS + Express从GET/POST Request 取值
过去无论哪一种网站应用程式的开发语言,初学者教学中第一次会提到的起手式,八九不离十就是GET/POST Request 的取值.但是,在Node.js + Express 的世界中,仿佛人人是高手,天 ...
- String,CString,TCHAR,char之间区别和联系
char是类型TCHAR也是!不过他可以通过是否定义了UNICODE宏来判断到底是char还是w_char; TCHAR是一种字符串类型,它让你在以MBCS和UNNICODE来build程序时可以使用 ...
- 【已解决】Android Studio下,gradle project sync failed 错误
原文:[已解决]Android Studio下,gradle project sync failed 错误 Android studio下突然报错 gradle project sync failed ...
- WPF控件深拷贝:序列化/反序列化
原文:WPF控件深拷贝:序列化/反序列化 今天DebugLZQ在做WPF拖动总结的时候,遇到了这个问题.baidu了下,貌似没有解决这个问题的权威答案,遂写下这篇博文. 我想做的事情是:拖动一个窗体内 ...
- PHP模拟单链表的数据结构
<?php /*** * 单链表 */ //节点,下标,节点名称,下一个节点的地址 class Node { public $id; public $name; public $next; pu ...