让MEF插上AOP的翅膀
什么是MEF
Git:https://github.com/MicrosoftArchive/mef
MEF也是一款ioc框架,貌似历史比较悠久了。
这里有一篇.net阵容里面主流ioc比较。
https://www.cnblogs.com/liping13599168/archive/2011/07/17/2108734.html
AOP
引用百度。
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
背景
线上有个报表项目,最近监控发现有个报表查询比较频繁,导致db压力大,现需要对查询频次较多的报表进行缓存。
代码实现
Nugget 引用Castle.Core
1自定义ExportProved
|
public { private
public AOPExportProvider(Func<ComposablePartCatalog> catalogResolver) { _exportProvider = new
//support recomposition _exportProvider.ExportsChanged += (s, e) => OnExportsChanged(e); _exportProvider.ExportsChanging += (s, e) => OnExportsChanging(e); }
public { get { return _exportProvider.SourceProvider; } set { _exportProvider.SourceProvider = value; } }
protected ImportDefinition definition, AtomicComposition atomicComposition) { IEnumerable<Export> exports = _exportProvider.GetExports(definition, atomicComposition); return exports.Select(export => new }
private { var value = innerExport.Value; IInterceptor[] attribs = value.GetType().GetCustomAttributes(typeof(IInterceptor), true).Cast<IInterceptor>().ToArray(); if (attribs.Length == 0) return value; ProxyGenerator generator = new object proxy = generator.CreateClassProxy(value.GetType(), attribs);
PropertyInfo[] propertyInfo= value.GetType().GetProperties(); Type proxyType = proxy.GetType().BaseType; foreach (var item in propertyInfo) { PropertyInfo property = proxyType.GetProperty(item.Name); if (property == null) continue; property.SetValue(proxy, item.GetValue(value,null),null); } return proxy; }
public { _exportProvider.Dispose(); } } |
2 在web启动的时候 指定自定义exportprovide
|
public { public { var container = ConfigureContainer(); ControllerBuilder.Current.SetControllerFactory(new var dependencyResolver = System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver; }
private { Func<ComposablePartCatalog> catalogResolver = () => {
AggregateCatalog catalog = new catalog.Catalogs.Add(new return catalog; }; AOPExportProvider provider = new CompositionContainer container = new provider.SourceProvider = container; AppDomain.CurrentDomain.SetData("Container", container); return container; } } |
3 实现Interceptor
|
[Export(typeof(IInterceptor))] public { private public CacheInterceptor(){ _cacheProvider = ((CompositionContainer)AppDomain.CurrentDomain.GetData("Container")).GetExportedValue<ICache>(); } private public { var qCachingAttribute = this.GetQCachingAttributeInfo(invocation.MethodInvocationTarget ?? invocation.Method); if (qCachingAttribute != null) { ProceedCaching(invocation, qCachingAttribute); } else { invocation.Proceed(); } } private { return method.GetCustomAttributes(true).FirstOrDefault(x => x.GetType() == typeof(QCachingAttribute)) as } private { var cacheKey = attribute.Key; if(string.IsNullOrEmpty(cacheKey)) cacheKey= GenerateCacheKey(invocation);
var cacheValue = _cacheProvider.Get(cacheKey, x => { return if (cacheValue != null) { invocation.ReturnValue = cacheValue; return; }
invocation.Proceed();
if (!string.IsNullOrWhiteSpace(cacheKey)) { _cacheProvider.Set(cacheKey, invocation.ReturnValue, TimeSpan.FromSeconds(attribute.AbsoluteExpiration)); } } private { var typeName = invocation.TargetType.Name; var methodName = invocation.Method.Name; var methodArguments = this.FormatArgumentsToPartOfCacheKey(invocation.Arguments);
return } //拼接缓存的键 private { var builder = new
builder.Append(typeName); builder.Append(_linkChar);
builder.Append(methodName); builder.Append(_linkChar);
foreach (var param in parameters) { builder.Append(param); builder.Append(_linkChar); }
return builder.ToString().TrimEnd(_linkChar); }
private { return methodArguments.Select(this.GetArgumentValue).Take(maxCount).ToList(); } //处理方法的参数,可根据情况自行调整 private { if (arg is return arg.ToString();
if (arg is return ((DateTime)arg).ToString("yyyyMMddHHmmss");
if (arg is return ((IQCachable)arg).CacheKey;
return } } |
4 定义拦截Attribute
|
[AttributeUsage(AttributeTargets.Method, Inherited = true)] public { public public } } |
5配置使用Interceptor
|
[Export(typeof(ICompanyDaily))] [CacheInterceptor] public { [Import] public [QCaching(AbsoluteExpiration =60*60*8)] public { string beginDate = sellDateBegin.ToString("yyyy-MM-dd"); string endDate = sellDateEnd.ToString("yyyy-MM-dd"); try { //dosomething return dtChart; } catch (Exception exp) { throw exp; } } |
Ps:拦截的方法必须是virtual
让MEF插上AOP的翅膀的更多相关文章
- 时序数据库(TSDB)-为万物互联插上一双翅膀
本文由 网易云发布. 时序数据库(TSDB)是一种特定类型的数据库,主要用来存储时序数据.随着5G技术的不断成熟,物联网技术将会使得万物互联.物联网时代之前只有手机.电脑可以联网,以后所有设备都会联 ...
- 让Storm插上CEP的翅膀 - Siddhi调研和集成
什么是 Siddhi? Siddhi 是一种 lightweight, easy-to-use, open source CEP(Complex Event Processing)引擎,由wso2公司 ...
- 插上腾飞的翅膀:为asp.net core添加protobuf支持
没时间解释了,快上车. 通过NuGet获取Zaabee.AspNetCoreProtobuf Install-Package Zaabee.AspNetCoreProtobuf 在Startup.cs ...
- 给PLSQL插上飞翔的翅膀-PLSQL优化
60-80% of database performance issues are related to poorly performing SQL,60-80%的数据库性能问题要归结于生产中糟糕的S ...
- 为Spring Cloud Config插上管理的翅膀
最近一致在更新Spring Cloud Config的相关内容,主要也是为这篇埋个伏笔,相信不少调研过Spring Cloud Config的用户都会吐槽它的管理能力太弱.因此,就有了下面为讲推荐的这 ...
- 插上翅膀,让Excel飞起来——xlwings(二)
在上一篇插上翅膀,让Excel飞起来——xlwings(一)中提到利用xlwings模块,用python操作Excel有如下的优点: xlwings能够非常方便的读写Excel文件中的数据,并且能够进 ...
- Spring Boot (六): 为 JPA 插上翅膀的 QueryDSL
在前面的文章中,我们介绍了 JPA 的基础使用方式,<Spring Boot (三): ORM 框架 JPA 与连接池 Hikari>,本篇文章,我们由入门至进阶的介绍一下为 JPA 插上 ...
- XCode4.5.6,iOS6.1下测试 判断当前设备,及其联网状态等; 关于设备插上后XCode检测不出的情况的说明
目录[-] 一.判断设备 二.判断网络连接状态 三.设备不显示的解决办法 一.判断设备 01 //设备名称 02 return [UIDevice currentDevice].name; 03 ...
- QT使用WOL实现远程一键开机(局域网,需要目标电脑的主板支持,并且插上网线,用udpSocket.writeDatagram一句话就可以)
功能:让关机的电脑一键开机,需要目标电脑的主板支持,并且插上网线: 效果:相当于手动按了一下目标电脑的开关机按钮. 没啥技术含量,简单开说... 1.获取目标机MAC地址 QByteArray sMa ...
随机推荐
- asp.net core 发布到iis session无法传递的问题
网站是用asp.net core 的Razor Pages开发的,其中用户登录用到了session,调试运行没有问题,但是发布到iis之后出现session无法记录的问题. 我用log记录查看了一下, ...
- 使用gethostname()函数和gethostbyname()函数获取主机相关信息
gethostname() : 返回本地主机的标准主机名. 原型如下: #include <unistd.h> int gethostname(char *name, size_t len ...
- ubuntu,装完PYTHON3 pip3 install 报错
ubuntu,装完PYTHON3 pip3 install 报错CalledProcessError: Command 'lsb_release -a' returned non-zero exit ...
- 在GNU/Linux下制作Windows 10安装U盘
今年春节回家期间,我需要将家里的一台安装了Debian Stretch的ZaReason笔记本电脑更换为Windows 10系统,好让爸妈从老台式机上的XP系统升级到新的平台上来.回家前,小仙女已在微 ...
- Cesium 中两种添加 model 方法的区别
概述 Cesium 中包含两种添加 model 的方法,分别为: 通过 viewer.entities.add() 函数添加 通过 viewer.scene.primitives.add() 函数添加 ...
- this指向及改变this指向的方法
一.函数的调用方式决定了 this 的指向不同,但总的原则,this指的是调用函数的那个对象: 1.普通函数调用,此时 this 指向 全局对象window function fn() { conso ...
- mybatis常用类起别名
在mybatis的配置文件中添加如下配置 <settings> <setting name="cacheEnabled" value="true&quo ...
- oracle中可能使用到的命令
借鉴他人 1.su – oracle 不是必需,适合于没有DBA密码时使用,可以不用密码来进入sqlplus界面.2.sqlplus /nolog 或sqlplus system/manager 或. ...
- Burnside引理和Polya定理之间的联系
最近,研究了两天的Burnside引理和Polya定理之间的联系,百思不得其解,然后直到遇到下面的问题: 对颜色限制的染色 例:对正五边形的三个顶点着红色,对其余的两个顶点着蓝色,问有多少种非等价的着 ...
- angularjs和ajax的结合使用 (三)
转眼九月份了,忙忙碌碌 发现今年还没开过张,写一篇吧. 15年在空闲时就倒腾过angularjs那玩意儿 ,觉得还是挺好的,李金龙那厚厚的一本书,只不过没有系统化应用.最主要的是原来有一个东西没有用到 ...