控制台应用程序使用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拦截到

 

posted @ 2021-01-19 15:47  温故纳新  阅读(448)  评论(0编辑  收藏  举报