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行为不光是监控行为,还可以配置日志行为,异常行为,缓存行为等等,如下图所示

转载于:https://www.cnblogs.com/menglin2010/p/11188662.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值