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