ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

<二>使用castle.core 简单实现AOP

2022-07-18 07:31:49  阅读:178  来源: 互联网

标签:core 调用 Console void WriteLine AOP invocation castle public


一、实现方式

  • 静态代理:代理模式,装饰器模式。
  • 动态代理:利用反射生成动态代理类。
  • 特性:利用.netcore框架自带的特性框架做封装。比如:Filter
  • Emit:  机器自动生成代理类。比如:castle.core
  • 静态编织:在代码编译的时候动态插入代码。

二、Castle.core使用的Emit的方式动态帮助我们生成代理类,不用我们自己去定义一个类来实现代理了。

1、nuget搜索castle.core 并引用

 2、使用Castle.core的CreateClassProxy动态生成代理类来实现AOP

  • 修改MySqlDBHelper 将show修改为虚方法,新增一个方法show1为非虚方法。
  •  public  class MySqlDBHelper: IDBHelper
        {
            public virtual void show()
            {
                Console.WriteLine("I am Mysql");
            }
            public void show1()
            {
                Console.WriteLine("I am Mysql1");
            }
        }
  • 新建一个CastleAOPProxy类来作为Castle.core的操作类
  •   public class CastleAOPProxy
        {
            public static void show()
            {
                ProxyGenerator generator = new ProxyGenerator();
                MyInterceptor interceptor=new MyInterceptor ();
                IDBHelper dbhelper = generator.CreateClassProxy<MySqlDBHelper>(interceptor);
                Console.WriteLine("生成的类型时:{0}", dbhelper.GetType());
                dbhelper.show();
       dbhelper.show1(); } }
  • 再新建一个类实现Castle.core的标准织入类StandardInterceptor的钩子方法
  •  public class MyInterceptor:StandardInterceptor
        {
            /// <summary>
            /// 调用前拦截
            /// </summary>
            /// <param name="invocation"></param>
            protected override void PreProceed(IInvocation invocation)
            {
                Console.WriteLine("调用前拦截,调用方法:" + invocation.Method.Name);
                base.PerformProceed(invocation);
            }
            /// <summary>
            /// 拦截的方法返回时调用
            /// </summary>
            /// <param name="invocation"></param>
            protected override void PreformProceed(IInvocation invocation)
            {
                Console.WriteLine("调用方法返回时拦截,调用方法:" + invocation.Method.Name);
                base.PostProceed(invocation);
            }
            /// <summary>
            /// 调用后拦截
            /// </summary>
            /// <param name="invocation"></param>
            protected override void PostProceed(IInvocation invocation)
            {
                Console.WriteLine("调用后拦截,调用方法:" + invocation.Method.Name);
                base.PreProceed(invocation);
            }
        }
  • 在Program调用一下看看
  • CastleAOPProxy.show();

     看看上面的执行结果,动态生成的代理类叫做MysqlDBHelperProxy了不是MysqlDBHelper,也就是说Castle给我们动态生成了代理类,并把MyInterceptor里面的钩子方法植入了。但是Show1没有运行钩子方法,也就是说ProxyGenerator只会对虚方法启作用。

 3、使用Castle.core的CreateInterfaceProxyWithTargetInterface动态生成代理类来实现AOP

  • 在CastleAOPProxy中新增一个ShowInterface的方法
  •  public static void ShowInterface()
            {
                ProxyGenerator generator = new ProxyGenerator();
                MyInterceptor interceptor = new MyInterceptor();
                IDBHelper dbhelper = new MySqlDBHelper();
                IDBHelper dbhelperProxy = generator.CreateInterfaceProxyWithTargetInterface<IDBHelper>(dbhelper,interceptor);
                Console.WriteLine("生成的类型时:{0}", dbhelper.GetType());
                dbhelperProxy.show();
                dbhelperProxy.show1();
            }
  •  修改program中的调用方法
  • CastleAOPProxy.ShowInterface();

     从上面结果看,不管是虚方法还是其他方法都可以实现了AOP。以上是两种使用代理动态织入的方式。

4、使用特性+Castle.core的CreateInterfaceProxyWithTargetInterface来实现AOP

  • 添加一个新的interceptor类叫MyAttributeInterceptor,通过对方式是否加了LogAttribute类型进行过滤是否执行植入逻辑
  •  public class MyAttributeInterceptor : StandardInterceptor
        {
            /// <summary>
            /// 调用前拦截
            /// </summary>
            /// <param name="invocation"></param>
            protected override void PerformProceed(IInvocation invocation)
            { 
                base.PerformProceed(invocation);
                if (!IsLog(invocation))
                    return;
                Console.WriteLine("调用时拦截,调用方法:" + invocation.Method.Name);          
            }
            /// <summary>
            /// 拦截的方法返回时调用
            /// </summary>
            /// <param name="invocation"></param>
            protected override void PostProceed(IInvocation invocation)
            { 
                base.PostProceed(invocation);
                if (!IsLog(invocation))
                    return;
                Console.WriteLine("调用后拦截,调用方法:" + invocation.Method.Name);          
            }
            /// <summary>
            /// 调用后拦截
            /// </summary>
            /// <param name="invocation"></param>
            protected override void PreProceed(IInvocation invocation)
            {      
                base.PreProceed(invocation);
                if (!IsLog(invocation))
                    return;
                Console.WriteLine("调用前拦截,调用方法:" + invocation.Method.Name);  
            }
    
            private bool IsLog(IInvocation invocation)
            {
                var method = invocation.Method;
                if (method.IsDefined(typeof(LogAttribute), true))
                {
                    return true;
                }
                return false;
            }
        }
  • 添加一个特性LogAttribute 
  •  public class LogAttribute:Attribute
        {
        }
  •  给IDBHelper的某个方法加上Log的特性
  • public interface  IDBHelper
        {
            [Log]
            void  show();
            void show1();
        }
  • 在CastleAOPProxy中新增一个ShowAttibuteInterface的方法
  •   public static void ShowAttibuteInterface()
            {
                ProxyGenerator generator = new ProxyGenerator();
                MyAttributeInterceptor interceptor = new MyAttributeInterceptor();
                IDBHelper dbhelper = new MySqlDBHelper();
                IDBHelper dbhelperProxy = generator.CreateInterfaceProxyWithTargetInterface<IDBHelper>(dbhelper, interceptor);
                Console.WriteLine("生成的类型时:{0}", dbhelper.GetType());
                dbhelperProxy.show();
                dbhelperProxy.show1();
            }
  • 在program中调用该方法 
  • CastleAOPProxy.ShowAttibuteInterface();

     如上图所示,添加了Log特性的Show方法显示了MyAttribute中的钩子方法。而show1没有添加的并没有显示。

标签:core,调用,Console,void,WriteLine,AOP,invocation,castle,public
来源: https://www.cnblogs.com/choii/p/16441535.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有