使用.net core中的类DispatchProxy实现AOP
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是软件开发中的一个热点,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性。
比如说三层的调用:UI => BLL => DAL,正常来说我们会在UI层调用BLL层某个类的某个方法,然后BLL层某个类的某个方法又会调用DAL层某个类的某个方法,可以说通常情况下我们都是这么干的;如果说UI调BLL、BLL调DAL是纵向的话,那么AOP就是横向的,AOP可以做到在调用BLL层或DAL层任意方法之前之后做一些统一的逻辑处理。
AOP的典型应用场景:日志记录、权限验证、异常处理、缓存等
目前,可以实现AOP的类库也有很多,如下:
AspectCore
Unity
Castle DynamicProxy
Dora.Interception
但是在.net core中有DispatchProxy类(命名空间:System.Reflection),提供实例化代理对象和处理其方法调度的机制,借助它我们可以自己实现AOP,直接看示例
定义一个消息接口IMessage,其中有一个发送消息Send和接收消息Receive的方法定义:
public interface IMessage
{
void Send(string content);
void Receive(string content);
}
定义电子邮件类EmailMessage实现消息接口IMessage,实现使用电子邮件发送和接收消息:
public class EmailMessage : IMessage
{
public void Send(string content)
{
Console.WriteLine("Send Email:" + content);
}
public void Receive(string content)
{
Console.WriteLine("Receive Email:" + content);
}
}
定义日志拦截器LogDispatchProxy 继承自DispatchProxy类,重写基类Invoke方法并在目标方法调用前后加上所需业务逻辑;然后定义TargetClass属性,该属性是目标方法所属类的实例
public class LogDispatchProxy : DispatchProxy
{
public object TargetClass { get; set; }
protected override object Invoke(MethodInfo targetMethod, object[] args)
{
Write("方法执行前");
var result = targetMethod.Invoke(TargetClass, args);
Write("方法执行后");
return result;
} private void Write(string content)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(content);
Console.ResetColor();
}
}
使用:
class Program
{
static void Main(string[] args)
{
//使用DispatchProxy类的静态方法Create生成代理类,其中Create是个泛型方法,泛型有两个值,第一个值必须是接口,第二个值必须是DispatchProxy的子类
IMessage messageDispatchProxy = DispatchProxy.Create<IMessage, LogDispatchProxy>();
//创建一个实现了IMessage接口的类的实例,并赋值给代理类的TargetClass属性
((LogDispatchProxy)messageDispatchProxy).TargetClass = new EmailMessage();
messageDispatchProxy.Send("早上好");
Console.WriteLine("=======================================");
messageDispatchProxy.Receive("中午好"); Console.ReadKey();
}
}
执行结果
我的理解:通过DispatchProxy.Create创建的代理类messageDispatchProxy 就是一个LogDispatchProxy类,并且利用我们提供的的实例实现了IMessage接口,所以messageDispatchProxy可以强转为LogDispatchProxy或IMessage
至此,我们没有通过任何第三方类库,自己实现了一个AOP
使用.net core中的类DispatchProxy实现AOP的更多相关文章
- [译]如何在ASP.NET Core中实现面向切面编程(AOP)
原文地址:ASPECT ORIENTED PROGRAMMING USING PROXIES IN ASP.NET CORE 原文作者:ZANID HAYTAM 译文地址:如何在ASP.NET Cor ...
- .NET Core中基类可以反射子类的成员
我们定义一个类DemoA,再定义一个类DemoB继承DemoA.当构造一个DemoB类对象后,我们可以通过其调用基类DemoA中的方法来反射子类DemoB的成员. 新建一个.NET Core控制台项目 ...
- ASP.NET Core中,UseDeveloperExceptionPage扩展方法会吃掉异常
在ASP.NET Core中Startup类的Configure方法中,有一个扩展方法叫UseDeveloperExceptionPage,如下所示: // This method gets call ...
- C# 中一些类关系的判定方法 C#中关于增强类功能的几种方式 Asp.Net Core 轻松学-多线程之取消令牌
1. IsAssignableFrom实例方法 判断一个类或者接口是否继承自另一个指定的类或者接口. public interface IAnimal { } public interface ID ...
- 在.NET Core中使用DispatchProxy“实现”非公开的接口
原文地址:"Implementing" a non-public interface in .NET Core with DispatchProxy 原文作者:Filip W. 译 ...
- EF Core中,通过实体类向SQL Server数据库表中插入数据后,实体对象是如何得到数据库表中的默认值的
我们使用EF Core的实体类向SQL Server数据库表中插入数据后,如果数据库表中有自增列或默认值列,那么EF Core的实体对象也会返回插入到数据库表中的默认值. 下面我们通过例子来展示,EF ...
- 在ASP.NET Core的startup类中如何使用MemoryCache
问: 下面的代码,在ASP.NET Core的startup类中创建了一个MemoryCache并且存储了三个键值“entryA”,“entryB”,“entryC”,之后想在Controller中再 ...
- .NET Core中的认证管理解析
.NET Core中的认证管理解析 0x00 问题来源 在新建.NET Core的Web项目时选择“使用个人用户账户”就可以创建一个带有用户和权限管理的项目,已经准备好了用户注册.登录等很多页面,也可 ...
- ASP.NET Core 中的那些认证中间件及一些重要知识点
前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...
随机推荐
- 初识Django,了解一下大概流程
学习Django一个礼拜了,对其有了一个大概的了解,自己画了一个简单的图,虽然有点丑,但是基本上已经把自己所想已经表达 写完这篇随笔之后发现自己逻辑表述的有点不太清晰,有点乱,哪里不对,希望各位指正 ...
- 10月27日Java整理
实验一:凯撒密码 import java.util.Scanner; //zhanxinwu,October,25,2016 public class Addmi { public static vo ...
- 用 Python 爬取网易严选妹子内衣信息,探究妹纸们的偏好
网易商品评论爬取 分析网页 评论分析 进入到网易精选官网,搜索“文胸”后,先随便点进一个商品. 在商品页面,打开 Chrome 的控制台,切换至 Network 页,再把商品页Python入门到精通学 ...
- Mysql综述(1)数据是如何读存的
引言 我们都知道,mysql中的索引,事务,锁等都是作为开发人员要重点掌握的知识面,但要想掌握理解好这些知识却并非易事. 其中原因之一就是这些概念都过于抽象,事实上如果都不懂mysql数据是以一种怎样 ...
- springboot配置logback日志
springboot配置logback日志 java web 下有好几种日志框架,比如:logback,log4j,log4j2(slj4f 并不是一种日志框架,它相当于定义了规范,实现了这个规范的日 ...
- Linux下yum与apt-get
linux系统基本上分两大类: 1.RedHat系列:Redhat.Centos.Fedora等 2.Debian系列:Debian.Ubuntu等 RedHat 系列 1 常见的安装包格式 rpm包 ...
- selenium-显式等待与隐式等待(3)
示例代码: from selenium.webdriver.support.wait import WebDriverWait as WD def find_element(self, by, loc ...
- Rsync服务常见问题
转---Rsync 故障排查整理 Rsync服务常见问题汇总讲解: 1. 客户端的错误现象:No route to host rsync服务端开启的iptables**防火墙** [root@nfs0 ...
- ES6基本语法入门
一.用let代替var声明变量 ES5中,我们可以在代码中任意位置声明变量,甚至可以重写已经声明的变量,ES6引入了一个let关键字,它是新的var. let language = 'javascri ...
- Django 从零开始
Django在Python的web开发框架中属于重量级的框架,功能多而全,但是相对的体积和坑也会比较多,但是其实学习Python的web开发个人觉得Django其实会比Flask好上手,特别是0基础的 ...