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();
}
}
}

最新文章

  1. yii2 日志(log)的配置与使用
  2. 用websocket实现后台推送消息
  3. 有序链表--Java实现
  4. 如何给php数组添加元素
  5. 在VS2017(VC15)上配置opencv4.0.1环境
  6. 初识Identity(一)
  7. 团队项目第6周 - Alpha阶段项目复审 - 天冷记得穿秋裤队
  8. Winform生成安装程序时配置自启动
  9. 20155227《网络对抗》Exp8 Web基础
  10. Cocos2d-x学习笔记(六)Label字体控制
  11. iconfont使用方法
  12. 轻松理解execl系列函数
  13. Linux下socket通信和多线程
  14. [MongoDB]------windos远程服务器部署连接
  15. java.time 时间和简单任务
  16. ldd pvs dis on solaris 10
  17. 【RF库Collections测试】Get From Dictionary
  18. eclipse如何设置UTF-8
  19. CI框架浅析(一)
  20. [Python爬虫] 之七:selenium webdriver定位不到元素的五种原因及解决办法(转载)

热门文章

  1. mongodb存储引擎WiredTiger
  2. Oracle 修改SID --不建议修改
  3. 后台(一)vue+element-ui(全局配置)
  4. vue+上传文件夹
  5. css添加了原始滚动条要隐藏滚动条的显示
  6. SDN与IXP
  7. ORACLE批量导入图片到BLOB字段
  8. selenium反爬机制
  9. 2.linux的增删改查
  10. 超详细Qt5.9.5移植攻略