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面向切面编程的更多相关文章

  1. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存

    代码已上传Github+Gitee,文末有地址 上回<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之九 || 依赖注入IoC学习 + ...

  2. Z从壹开始前后端分离【 .NET Core2.0/3.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存

    本文梯子 本文3.0版本文章 代码已上传Github+Gitee,文末有地址 大神反馈: 零.今天完成的深红色部分 一.AOP 之 实现日志记录(服务层) 1.定义服务接口与实现类 2.在API层中添 ...

  3. AOP(面向切面编程)大概了解一下

    前言 上一篇在聊MemoryCache的时候,用到了Autofac提供的拦截器进行面向切面编程,很明显能体会到其优势,既然涉及到了,那就趁热打铁,一起来探探面向切面编程. 正文 1. 概述 在软件业, ...

  4. AOP 面向切面编程, Attribute在项目中的应用

    一.AOP(面向切面编程)简介 在我们平时的开发中,我们一般都是面对对象编程,面向对象的特点是继承.多态和封装,我们的业务逻辑代码主要是写在这一个个的类中,但我们在实现业务的同时,难免也到多个重复的操 ...

  5. AOP面向切面编程的四种实现

     一.AOP(面向切面编程)的四种实现分别为最原始的经典AOP.代理工厂bean(ProxyFacteryBean)和默认自动代理DefaultAdvisorAutoProxyCreator以及Bea ...

  6. Javascript aop(面向切面编程)之around(环绕)

    Aop又叫面向切面编程,其中“通知”是切面的具体实现,分为before(前置通知).after(后置通知).around(环绕通知),用过spring的同学肯定对它非常熟悉,而在js中,AOP是一个被 ...

  7. Method Swizzling和AOP(面向切面编程)实践

    Method Swizzling和AOP(面向切面编程)实践 参考: http://www.cocoachina.com/ios/20150120/10959.html 上一篇介绍了 Objectiv ...

  8. [转] AOP面向切面编程

    AOP面向切面编程 AOP(Aspect-Oriented Programming,面向切面的编程),它是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...

  9. C# AOP 面向切面编程之 调用拦截

    有时候我们需要在代码中对方法调用进行拦截,并修改参数和返回值,这种操作叫做AOP(面向切面编程) 不过需要注意的是,AOP的效率很慢,在需要高效率场合慎用. 以下是C#的AOP方法: 首先建立一个控制 ...

随机推荐

  1. Vue.js 中的 v-cloak 指令

    可以使用 v-cloak 指令设置样式,这些样式会在 Vue 实例编译结束时,从绑定的 HTML 元素上被移除. 当网络较慢,网页还在加载 Vue.js ,而导致 Vue 来不及渲染,这时页面就会显示 ...

  2. MySQL5.5安装步骤

    原文链接:https://blog.csdn.net/m0_38025207/article/details/80723095 1.首先进入的是安装引导界面 2.然后进入的是类型选择界面,这里有3个类 ...

  3. Python3 输入和输出(一)

    1.输出格式美化 Python两种输出值的方式: 表达式语句和 print() 函数. 第三种方式是使用文件对象的 write() 方法,标准输出文件可以用 sys.stdout 引用. 如果希望输出 ...

  4. Tkinter 之Place布局

    一.参数说明 参数 作用 anchor  控制组件在 place 分配的空间中的位置"n", "ne", "e", "se&quo ...

  5. S标签的CheckBox显示和回显

    var ytfl=document.getElementsByName("jcrwModel.ytfl"); var jg='${jcrwModel.ytfl}';    for( ...

  6. My algorithmic road

    序言 初窥门径 1 第一题 素数的烦恼 离开了家乡,你到达了数字之地,在这里数字2总感觉自己是自然数中最独特的一个,他只有一和它本身两个因数,为此它十分苦恼.为了不再寂寞,他建立了素数王国,他请求许多 ...

  7. DataSync 异构数据同步

    RAC, Data Gurad, Stream 是Oracle 高可用性体系中的三种工具,每个工具即可以独立应用,也可以相互配合. 他们各自的侧重点不同,适用场景也不同. RAC 它的强项在于解决单点 ...

  8. 【Oracle/Java】多表插删数据单多线程比较

    源码下载:https://files.cnblogs.com/files/xiandedanteng/OracleAccessComparison20191117.rar 做这个比较工程初衷是:我在单 ...

  9. imfilter

    图像处理函数详解——imfilter功能:对任意类型数组或多维图像进行滤波.用法:B = imfilter(A,H) B = imfilter(A,H,option1,option2,...) 或写作 ...

  10. android: Context引起的内存泄露问题

    错误的使用Context可能会导致内存泄漏,典型的例子就是单例模式时引用不合适的Context. public class SingleInstance { private static Single ...