六、UnityConfig实现AOP

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

一、定义1个用户接口app

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

        User GetUser(User user);
    }
}

二、实现用户这个接口性能

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

        public User GetUser(User user)
        {
            Console.WriteLine("获得用户信息。");
            return user;
        }
    }
}

三、Unity配置文件
3.一、须要引用以下图这5个程序集ui

3.一、Unity.Config配置文件的注册顺序就是额外逻辑的调用顺序,而后才是业务方法自己,可是扩展逻辑能够是业务方法后this

<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.二、接口方法不须要某个AOP扩展怎么办呢?在方法上加个CustomNOAOPAttribute自定义属性,在执行MonitorBehavior类的Invoke方法里用特性input.Target.GetType().IsDefined(typeof(CustomNOAOPAttribute), true)去判断一下
spa

3.三、MonitorBehavior监控行为额外逻辑代码pwa

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

四、客户端调用UserService服务3d

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

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

 

七、项目截图,咱们能够配置多个AOP行为不光是监控行为,还能够配置日志行为,异常行为,缓存行为等等,以下图所示
日志

相关文章
相关标签/搜索