在 CAP 中使用 AOP ( Castle.DynamicProxy )
简介
本篇文章主要介绍如何在 CAP 中集成使用 Castle.DynamicProxy,Castle DynamicProxy 是一个用于在运行时动态生成轻量级.NET代理的库。代理对象允许在不修改类代码的情况下截取对对象成员的调用。可以代理类和接口,但是只能拦截虚拟成员。
为什么需要使用 AOP
Castle.DynamicProxy 为 AOP 的一种实现方式,AOP 为 Aspect Oriented Programming 的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。
Castle.DynamicProxy 可以帮助你方便的创建代理对象,代理对象可以帮助构建灵活的应用程序体系结构,因为它允许将功能透明地添加到代码中,而无需对其进行修改。例如,可以代理一个类来添加日志记录或安全检查,而无需使代码知道已添加此功能。
下面可以看到如何在 CAP 中集成使用 Castle.DynamicProxy。
Getting Started
1、安装 NuGet 包
在 集成了 CAP 的项目中安装包,有关如何集成 CAP 的文档请看这里。
注意,Castle.DynamicProxy 这个包已经被废弃,请使用最新的 Castle.Core 包。
<PackageReference Include="Castle.Core" Version="4.4.1" />
2、创建一个 Castle 切面拦截器
可以在这里 dynamicproxy.md 找到相关的文档。
下面为示例代码,继承 Castle 提供的 IInterceptor 接口即可:
[Serializable]
public class MyInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("Before target call");
try
{
invocation.Proceed();
}
catch (Exception)
{
Console.WriteLine("Target threw an exception!");
throw;
}
finally
{
Console.WriteLine("After target call");
}
}
}
拦截器此处命名为 MyInterceptor,你可以在其中处理你的业务逻辑,比如添加日志或其他的一些行为。
3、创建 IServiceCollection 的扩展类
为 IServiceCollection 创建扩展,方面后续调用。
using Castle.DynamicProxy;
public static class ServicesExtensions
{
public static void AddProxiedSingleton<TImplementation>(this IServiceCollection services)
where TImplementation : class
{
services.AddSingleton(serviceProvider =>
{
var proxyGenerator = serviceProvider.GetRequiredService<ProxyGenerator>();
var interceptors = serviceProvider.GetServices<IInterceptor>().ToArray();
return proxyGenerator.CreateClassProxy<TImplementation>(interceptors);
});
}
}
此处我创建了一个 Singleton 声明周期的扩展方法,建议所有 CAP 的订阅者都创建为 Singleton 即可,因为在 CAP 内部实际执行的时候也会创建一个 scope 来执行,所以无需担心资源释放问题。
4、创建 CAP 订阅服务
创建一个 CAP 订阅类,注意不能放在 Controller 中了。
注意:方法需要为虚方法 virtual,才能被 Castle 重写,别搞忘了加!!!
public class CapSubscribeService: ICapSubscribe
{
[CapSubscribe("sample.rabbitmq.mysql")]
public virtual void Subscriber(DateTime p)
{
Console.WriteLine($@"{DateTime.Now} Subscriber invoked, Info: {p}");
}
}
5、在 Startup 中集成
public void ConfigureServices(IServiceCollection services)
{
// 添加 Castle 的代理生成器
services.AddSingleton(new ProxyGenerator());
// 添加第2步的自定义的拦截类,声明周期为
services.AddSingleton<IInterceptor, MyInterceptor>();
// 此处为上面的扩展方法, 添加 CAP 订阅 Service
services.AddProxiedSingleton<CapSubscribeService>();
services.AddCap(x =>
{
x.UseMySql("");
x.UseRabbitMQ("");
x.UseDashboard();
});
// ...
}
以上就完成了所有的集成工作,可以开始进行测试了,有问题欢迎到 Github issue 反馈。
注意: CAP 需要使用 5.0 + 版本,目前只有 preview 版本。
总结
以上就是如何在 CAP 中使用 Castle 进行代理,如果你觉得有用,欢迎右下角点赞。
参考地址:
Castle DynamicProxy 的文档地址:
https://github.com/castleproject/Core/blob/master/docs/dynamicproxy.md
CAP 的 Github 地址:
https://github.com/dotnetcore/cap
本文地址:http://www.cnblogs.com/savorboard/p/cap-castle.html
作者博客:Savorboard
本文原创授权为:署名 - 非商业性使用 - 禁止演绎,协议普通文本 | 协议法律文本
在 CAP 中使用 AOP ( Castle.DynamicProxy )的更多相关文章
- Castle DynamicProxy基本用法(AOP)
本文介绍AOP编程的基本概念.Castle DynamicProxy(DP)的基本用法,使用第三方扩展实现对异步(async)的支持,结合Autofac演示如何实现AOP编程. AOP 百科中关于AO ...
- 使用Castle DynamicProxy (AOP)
在本文中,我将引导您了解.NET环境中的面向方面编程(AOP)概念,以及如何使用Castle DynamicProxy创建和附加方面.在我们开始之前,让我快速介绍AOP和 IoC.如果您已经熟悉这些 ...
- .Net中的AOP读书笔记系列之AOP介绍
返回<.Net中的AOP>系列学习总目录 本篇目录 AOP是什么? Hello,World! 小结 本系列的源码本人已托管于Coding上:点击查看,想要注册Coding的可以点击该连接注 ...
- .Net中的AOP系列之《单元测试切面》
返回<.Net中的AOP>系列学习总目录 本篇目录 使用NUnit编写测试 编写和运行NUnit测试 切面的测试策略 Castle DynamicProxy测试 测试一个拦截器 注入依赖 ...
- .Net中的AOP系列之《拦截位置》
返回<.Net中的AOP>系列学习总目录 本篇目录 位置拦截 .Net中的字段和属性 PostSharp位置拦截 真实案例--懒加载 .Net中的懒加载 使用AOP实现懒加载 如何懒加载字 ...
- .Net中的AOP系列之《间接调用——拦截方法》
返回<.Net中的AOP>系列学习总目录 本篇目录 方法拦截 PostSharp方法拦截 Castle DynamicProxy方法拦截 现实案例--数据事务 现实案例--线程 .Net线 ...
- 基于Autofac, Castle.DynamicProxy的动态WCF解决方案(原创)
本方案解决了下面3个主要的问题: 1.减少配置,为了避免每次新增service都需要去修改配置文件,包括服务器端跟各个客户端的. 2.能够使用函数重载,泛型函数,以及泛型类. 3.使项目能够快速地在w ...
- 【转】在.Net中关于AOP的实现
原文地址:http://www.uml.org.cn/net/201004213.asp 一.AOP实现初步 AOP将软件系统分为两个部分:核心关注点和横切关注点.核心关注点更多的是Domain Lo ...
- Net中的AOP
.Net中的AOP系列之<单元测试切面> 返回<.Net中的AOP>系列学习总目录 本篇目录 使用NUnit编写测试 编写和运行NUnit测试 切面的测试策略 Castle ...
随机推荐
- PyQt(Python+Qt)学习随笔:QTableWidget的属性
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 1.概述 除了从父类继承的属性外,在Designer中QTableWidget只有两个属性,就是行数 ...
- PyQt(Python+Qt)学习随笔:QTreeWidget的topLevelItemCount属性
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTreeWidget的topLevelItemCount属性是一个只读属性,用于保存树型部件中顶层 ...
- html标签和body标签的区别
首先想要总结这个问题就是因为在开发的过程中,在设置body的高度的时候,在浏览器窗口中并不起作用,一直都会显示是浏览器窗口的大小,所以想要搞清楚这面的原因. 一.前提 在页面的设计中,当我们没有为一个 ...
- 【SDOI2017】天才黑客(前后缀优化建图 & 最短路)
Description 给定一张有向图,\(n\) 个点,\(m\) 条边.第 \(i\) 条边上有一个边权 \(c_i\),以及一个字符串 \(s_i\). 其中字符串 \(s_1, s_2, \c ...
- Java集合源码分析(二)——ArrayList
简介 ArrayList 是一个数组列表,相当于 动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractList,实现了List, RandomAccess, Cloneabl ...
- Vue-组件传值:子传父和兄弟组件间常见的传值方式
前言 上篇介绍了我对vue组件化的理解和父组件对子组件传值的方式,这篇介绍下常见的子传父和兄弟组件间的传值方式 目录 子组件向父组件传值 任意组件间的传值方式 正文 子组件向父组件传值 关键知识点:$ ...
- mysql 5.7升级8.0
升级前准备: [root@node01 ~]# mysql -V mysql Ver 14.14 Distrib 5.7.25, for linux-glibc2.12 (x86_64) using ...
- 解析SwiftUI布局细节(一)
前言 在前面的文章中谈了谈对SwiftUI的基本的认识,以及用我们最常见的TB+NA的方式搭建了一个很基本的场景来帮助认识了一下SwiftUI,具体的文章可以在SwiftUI分类部分查找,这篇我准备在 ...
- windows 10 1909 无法启用 .NET Framework 解决
安装某应用,运行提示: 应用程序无法正常启动(0xc0000135) 应该是缺少 .net framework. 控制面板-程序-"启用或关闭windows功能" 勾选.NET F ...
- js下 Day19、综合案例
一.吸顶楼层 效果图: 功能思路分析: 1. 面向对象框架 2. 渲染导航 \1. 数据 \2. 对象结构的数据用for in遍历 \3. 渲染时将属性名设为锚点(a标签的href) 3. 渲染车系 ...