C#使用Castle实现AOP面向切面编程
Castle.Core 本质是创建继承原来类的代理类,重写虚方法实现AOP功能。个人觉得比Autofac用着爽
使用方式比较简单,先新建一个控制台项目,然后在Nuget上搜索Castle.Core并安装,如下顺序:

或者通过命令安装:
Install-Package Castle.Core -Version 3.3.
安装成功之后,如下图:

1. 创建拦截器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//先在Nuget上搜索Castle安装
using Castle.DynamicProxy; namespace CastleDEMO
{
/// <summary>
/// 拦截器 需要实现 IInterceptor接口 Intercept方法
/// </summary>
public class DA_LogInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
try
{
DateTime begin = DateTime.Now; Console.WriteLine("开始DAL {0}调用!", invocation.Method.Name); //在被拦截的方法执行完毕后 继续执行
invocation.Proceed(); DateTime end = DateTime.Now;
Console.WriteLine("结束DAL {0}调用!耗时:{1}ms", invocation.Method.Name, (end - begin).TotalMilliseconds);
}
catch (Exception ex)
{
string methodName = "DA_" + invocation.TargetType.ToString() + "." + invocation.Method.Name;
Console.WriteLine("{0}方法错误:{1}", methodName, ex.Message);
//如果没有定义异常处理返回值,就直接抛异常
if (!invocation.Method.IsDefined(typeof(ExceptionReturnAttribute), false))
throw;
var ls = invocation.Method.GetCustomAttributes(typeof(ExceptionReturnAttribute), false);
if (null == ls || ls.Length <= )
throw; ExceptionReturnAttribute v = (ExceptionReturnAttribute)ls[];
if (null == v.Value && null == v.Type)
{
invocation.ReturnValue = null;
return;
}
if (null != v.Value)
{
invocation.ReturnValue = v.Value;
return;
}
if (null != v.Type)
{
invocation.ReturnValue = Activator.CreateInstance(v.Type);
return;
}
}
} /// <summary>
/// <para>DAO层异常时,不throw,返回设定的值.</para>
/// <para>1. 返回复杂类型,使用Type,复杂类型需要有无参的构造函数</para>
/// <para>2. 返回简单类型,使用value</para>
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class ExceptionReturnAttribute : System.Attribute
{
/// <summary>
/// 返回复杂类型,使用Type,复杂类型需要有无参的构造函数
/// </summary>
public Type Type { get; set; } /// <summary>
/// 返回简单类型,使用value
/// </summary>
public object Value { get; set; }
}
}
}
2. 创建拦截容器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Castle.DynamicProxy; namespace CastleDEMO
{
/// <summary>
/// Dao 类的接口
/// 继承实现BaseDao的类,其相关接口访问的公共方法必须要声明 virtual 方法才能被拦截器拦截。
/// </summary>
public abstract class BaseDao
{ } /// <summary>
/// Dao容器,必须依赖于此类来创建Dao对象,使Dao受控,可进行检查等
/// </summary>
public class DaoContainer
{
//ProxyGenerator上自身有缓存
//实例化【代理类生成器】
public static ProxyGenerator generator = new ProxyGenerator();
public static T GetDao<T>() where T : BaseDao
{
//实例化【拦截器】
DA_LogInterceptor interceptor = new DA_LogInterceptor();
//使用【代理类生成器】创建T对象,而不是使用new关键字来实例化
return generator.CreateClassProxy<T>(interceptor);
}
}
}
3. 新建实例类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace CastleDEMO
{
public abstract class PersonDAL : BaseDao
{
/// <summary>
/// 必须是虚方法才能被拦截器拦截
/// </summary>
public virtual void SayHello()
{
Console.WriteLine("我是虚方法{0}方法", "SayHello");
}
public virtual void SayName(string name)
{
Console.WriteLine("我是虚方法{0}方法,参数值:{1}", "SayName", name);
}
public abstract void AbstactSayOther();
public void SayOther()
{
Console.WriteLine("我是普通方法{0}方法", "SayOther");
}
}
}
4. 测试
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace CastleDEMO
{
public class Program
{
public static void Main(string[] args)
{
PersonDAL person = DaoContainer.GetDao<PersonDAL>();
Console.WriteLine("当前类型:{0},父类型:{1}", person.GetType(), person.GetType().BaseType);
Console.WriteLine();
person.SayHello();//拦截
Console.WriteLine();
person.SayName("Never、C");//拦截
Console.WriteLine();
person.SayOther();//普通方法,无法拦截
//person.AbstactSayOther();//抽象方法,可以拦截(但是如果方法没实现拦截时会报错)
Console.ReadLine();
}
}
}

C#使用Castle实现AOP面向切面编程的更多相关文章
- 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存
代码已上传Github+Gitee,文末有地址 上回<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之九 || 依赖注入IoC学习 + ...
- Z从壹开始前后端分离【 .NET Core2.0/3.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存
本文梯子 本文3.0版本文章 代码已上传Github+Gitee,文末有地址 大神反馈: 零.今天完成的深红色部分 一.AOP 之 实现日志记录(服务层) 1.定义服务接口与实现类 2.在API层中添 ...
- AOP(面向切面编程)大概了解一下
前言 上一篇在聊MemoryCache的时候,用到了Autofac提供的拦截器进行面向切面编程,很明显能体会到其优势,既然涉及到了,那就趁热打铁,一起来探探面向切面编程. 正文 1. 概述 在软件业, ...
- AOP 面向切面编程, Attribute在项目中的应用
一.AOP(面向切面编程)简介 在我们平时的开发中,我们一般都是面对对象编程,面向对象的特点是继承.多态和封装,我们的业务逻辑代码主要是写在这一个个的类中,但我们在实现业务的同时,难免也到多个重复的操 ...
- AOP面向切面编程的四种实现
一.AOP(面向切面编程)的四种实现分别为最原始的经典AOP.代理工厂bean(ProxyFacteryBean)和默认自动代理DefaultAdvisorAutoProxyCreator以及Bea ...
- Javascript aop(面向切面编程)之around(环绕)
Aop又叫面向切面编程,其中“通知”是切面的具体实现,分为before(前置通知).after(后置通知).around(环绕通知),用过spring的同学肯定对它非常熟悉,而在js中,AOP是一个被 ...
- Method Swizzling和AOP(面向切面编程)实践
Method Swizzling和AOP(面向切面编程)实践 参考: http://www.cocoachina.com/ios/20150120/10959.html 上一篇介绍了 Objectiv ...
- [转] AOP面向切面编程
AOP面向切面编程 AOP(Aspect-Oriented Programming,面向切面的编程),它是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...
- C# AOP 面向切面编程之 调用拦截
有时候我们需要在代码中对方法调用进行拦截,并修改参数和返回值,这种操作叫做AOP(面向切面编程) 不过需要注意的是,AOP的效率很慢,在需要高效率场合慎用. 以下是C#的AOP方法: 首先建立一个控制 ...
随机推荐
- 拷贝和遍历DOM树
一.浅拷贝: 拷贝就是复制,就相当于把一个对象中的所有内容,复制一份给另一个对象,直接复制, 或者说,就是把一个对象的地址给了另外一个对象,他们的指向相同,两个对象之间有相同的属性或者方法,都可以使用 ...
- scrapy 分布式爬虫- RedisSpider
爬去当当书籍信息 多台机器同时爬取,共用一个redis记录 scrapy_redis 带爬取的request对象储存在redis中,每台机器读取request对象并删除记录,经行爬取.实现分布式爬虫 ...
- Gluon学习03-基础数据类型Ndarray
Gluon学习03-基础数据类型Ndarray 小书匠 kindle 目录,方便快速定位: 1.安装cuda与cudnn 2.安装mxnet-gpu 本机环境介绍: 系统:Linuxmint Pyt ...
- mysql5.7版本以上下载安装
1.mysql官网下载地址:https://downloads.mysql.com/archives/community/ 2.下载完成后解压,解压后如图: 3.放置位置,把解压好的文件夹放在自己喜欢 ...
- 配置Spring Data Redis
事前准备 1.下载redis https://github.com/MicrosoftArchive/redis/releases/tag/win-3.2.100 2.下载redis可视化工具 htt ...
- AWS API Gateway Swagger定义
导出Swagger接口定义文件 在AWS API Gateway界面上,可以导出swagger接口定义文件. 而后利用Node js swagger-ui 依赖,生成swagger接口地址 Cloud ...
- 一篇文章彻底搞懂base64编码原理
开始 在互联网中的每一刻,你可能都在享受着Base64带来的便捷,但对于Base64的基础原理又了解多少?今天这篇文章带领大家了解一下Base64的底层实现. base64是什么东东呢? Base64 ...
- Android 系统添加SELinux权限
本文为博主原创文章,转载请注明出处:https://i.cnblogs.com/EditPosts.aspx?postid=11185476 CPU:RK3288 系统:Android 5.1 SEL ...
- jQuery 设置select,radio的值,无法自动触发绑定的change事件
一.问题 今天在对select和radio做change事件绑定后,手动设置其value值,但是不能触发change事件 二.解决 使用trigger方法手动触发
- [转][C#]dll 引用
本文转自:https://zhidao.baidu.com/question/1176198151354174139.html 首先,对应关系: C++ C#===================== ...