控制台应用程序使用Autofac实现AOP类代理拦截
1 安装依赖包
安装 Autofac 和 Autofac.Extras.DynamicProxy
2 定义拦截器类
using System; using System.Linq; using Castle.DynamicProxy; // 添加引用 namespace ConsoleApp_AutofacAop { /// <summary> /// 拦截器需要实现 IInterceptor 接口 /// </summary> public class LogInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { #region 方法执行前 string beforeExe_msg = string.Format("方法执行前:拦截[{0}]类下的方法[{1}]的参数是[{2}]", invocation.InvocationTarget.GetType(), invocation.Method.Name, string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray())); Console.WriteLine(beforeExe_msg); #endregion #region 方法执行 invocation.Proceed(); #endregion #region 方法执行完成后 string afterExe_msg = string.Format("方法执行完毕,返回结果:{0}", invocation.ReturnValue); Console.WriteLine(afterExe_msg); #endregion } } }
3 定义需要被拦截的类,在被拦截的类上加上 Intercept 特性
using System; using System.Collections.Generic; using System.Text; using Autofac.Extras.DynamicProxy; // 添加引用 namespace ConsoleApp_AutofacAop { /// <summary> /// 定义被拦截的类 /// </summary> [Intercept(typeof(LogInterceptor))] // Person 使用 LogInterceptor拦截器 public class Person { public int Age { get; set; } public Person(){} // 非虚方法不会被拦截到 public void Method_NoVirtua() { Console.WriteLine("Method_NoVirtua"); } public virtual void Method2() { Console.WriteLine("Method2"); } public virtual string Method3(string para1,string para2) { Console.WriteLine("Method3"); return para1 + "&" + para2; } } }
被拦截类上的方法需要是virtual虚方法,不然不会被拦截到
4 初始化Aufofac容器,然后注册拦截器和被拦截的类,并且在被拦截的类上启用类拦截
#region 在应用的启动地方构造Autofac容器并注册依赖 // 定义容器 private static IContainer Container { get; set; } /// <summary> /// 初始化Autofac /// </summary> private static void AutofacInit() { var builder = new ContainerBuilder(); // 注册依赖 builder.RegisterType<LogInterceptor>(); // 注册拦截器 builder.RegisterType<Person>().EnableClassInterceptors(); // 注册被拦截的类并启用类拦截 Container = builder.Build(); } #endregion
5 测试
完整的测试代码如下
using System; using Autofac; using Autofac.Extras.DynamicProxy; namespace ConsoleApp_AutofacAop { class Program { static void Main(string[] args) { AutofacInit(); TestMethod(); Console.ReadLine(); } #region 在应用的启动地方构造Autofac容器并注册依赖 // 定义容器 private static IContainer Container { get; set; } /// <summary> /// 初始化Autofac /// </summary> private static void AutofacInit() { var builder = new ContainerBuilder(); // 注册依赖 builder.RegisterType<LogInterceptor>(); // 注册拦截器 builder.RegisterType<Person>().EnableClassInterceptors(); // 注册被拦截的类并启用类拦截 Container = builder.Build(); } #endregion #region 测试方法 public static void TestMethod() { Console.WriteLine("使用自己new创建的对象无法使用容器提供的ioc"); var person1 = new Person(); person1.Method_NoVirtua(); person1.Method2(); person1.Method3("person1_p1", "person1_p2"); Console.WriteLine(); using (var scope = Container.BeginLifetimeScope()) { var person = scope.Resolve<Person>(); person.Method_NoVirtua(); person.Method2(); person.Method3("person_p1", "person_p2"); } } #endregion } }
运行结果:
注意:只有是Autofac容器创建的对象实例才会被aop拦截,通过其他方法创建的对象实例不会被autofac的aop拦截到