zoukankan      html  css  js  c++  java
  • 6、UnityConfig实现AOP

    需求:我们需要给已经开发好的服务如这里的UserService,添加额外的执行逻辑,但是又不想破坏原有的服务,如:我们需要给UserService添加监控逻辑,监控的目的是看UserService服务里的RegUser方法和GetUser方法的执行时间消耗

    1、定义1个用户接口

    namespace UnityConfigAOP
    {
        public interface IUserService
        {
            void RegUser(User user);
    
            User GetUser(User user);
        }
    }

    2、实现用户这个接口

    namespace UnityConfigAOP
    {
        public class UserService:IUserService
        {
            public void RegUser(User user)
            {
                Console.WriteLine("用户已注册。");
            }
    
            public User GetUser(User user)
            {
                Console.WriteLine("得到用户信息。");
                return user;
            }
        }
    }

    3、Unity配置文件
    3.1、需要引用如下图这5个程序集

    3.1、Unity.Config配置文件的注册顺序就是额外逻辑的调用顺序,然后才是业务方法本身,但是扩展逻辑可以是业务方法后

    <configuration>
      <configSections>
        <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
        <!--Microsoft.Practices.Unity.Configuration.UnityConfigurationSection-->
      </configSections>
      <unity>
        <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
        <containers>
          <container name="aopContainer">
            <extension type="Interception"/>
            <register type="UnityConfigAOP.IUserService,UnityConfigAOP" mapTo="UnityConfigAOP.UserService,UnityConfigAOP">
              <interceptor type="InterfaceInterceptor"/>
              <interceptionBehavior type="UnityConfigAOP.AOPBehavior.MonitorBehavior, UnityConfigAOP"/>
            </register>
          </container>
        </containers>
      </unity>
    </configuration>

    3.2、接口方法不需要某个AOP扩展怎么办呢?在方法上加个CustomNOAOPAttribute自定义属性,在执行MonitorBehavior类的Invoke方法里用特性input.Target.GetType().IsDefined(typeof(CustomNOAOPAttribute), true)去判断一下

    3.3、MonitorBehavior监控行为额外逻辑代码

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using System.Threading.Tasks;
    using Unity.Interception.InterceptionBehaviors;
    using Unity.Interception.PolicyInjection.Pipeline;
    
    namespace UnityConfigAOP.AOPBehavior
    {
        /// <summary>
        /// 性能监控的AOP扩展
        /// </summary>
        public class MonitorBehavior : IInterceptionBehavior
        {
            public IEnumerable<Type> GetRequiredInterfaces()
            {
                return Type.EmptyTypes;
            }
    
            public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
            {
                var type = input.Target.GetType();
                string methodName = input.MethodBase.Name;
                if (type.IsDefined(typeof(CustomNOAOPAttribute), true))
                {
                    var method = getNext().Invoke(input, getNext);//后续逻辑执行
                    return method;
                }
    
                MethodInfo currentMethod = type.GetMethod(methodName);
                if (currentMethod.IsDefined(typeof(CustomNOAOPAttribute), true))//检查方法有没有定义此属性
                {
                    var method = getNext().Invoke(input, getNext);//后续逻辑执行
                    return method;
                }
    
                Console.WriteLine(this.GetType().Name);
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
    
                var methodReturn = getNext().Invoke(input, getNext);//后续逻辑执行
    
                stopwatch.Stop();
                Console.WriteLine($"{this.GetType().Name}统计方法{methodName}执行耗时{stopwatch.ElapsedMilliseconds}ms");
    
                return methodReturn;
            }
    
            public bool WillExecute
            {
                get { return true; }
            }
        }
    }

    4、客户端调用UserService服务

    namespace UnityConfigAOP
    {
        class Program
        {
            static void Main(string[] args)
            {
                User user = new User()
                {
                    Name = "David.Meng",
                    Password = "123456"
                };
                //配置UnityContainer
                IUnityContainer container = new UnityContainer();
                ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
                fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\Unity.Config");
                Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
    
                UnityConfigurationSection configSection = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
                configSection.Configure(container, "aopContainer");
    
                IUserService userService = container.Resolve<IUserService>();
                userService.RegUser(user);
                userService.GetUser(user);
            }
        }
    }

    5、调试代码
    执行userService.RegUser(user);代码的时候,并没有直接进入到RegUser(User user);方法里面,而是先进到MonitorBehavior类的Invoke方法里,直到执行到getNext().Invoke(input, getNext);这句代码才真正的进入到RegUser(User user);方法里面

     

    7、项目截图,我们可以配置多个AOP行为不光是监控行为,还可以配置日志行为,异常行为,缓存行为等等,如下图所示

  • 相关阅读:
    微软忘记修复Mac Office2004/2008安全漏洞 狼人:
    资深黑客谈:安全趋势正在向应用层发展 狼人:
    Web应用防火墙之前世今生 狼人:
    RSA技术总监Bill Duane:安全正因云而改变 狼人:
    微软11月将发布3个补丁 修复11处漏洞 狼人:
    选择透明在按钮上添加图片
    企业组织不管你学的是什么专业,你都应该多少懂些管理学的东西
    最大数组连续子向量的最大和
    异步请求再探异步 ASP.NET 页
    谷歌平台谷歌将推安卓游戏中心 整合社交挖角iOS
  • 原文地址:https://www.cnblogs.com/menglin2010/p/11188662.html
Copyright © 2011-2022 走看看