需求:我们需要给已经开发好的服务如这里的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 = ""
};
//配置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行为不光是监控行为,还可以配置日志行为,异常行为,缓存行为等等,如下图所示

6、UnityConfig实现AOP的更多相关文章

  1. 第七节:WebApi与Unity整合进行依赖注入和AOP的实现

    一. IOC和DI 1. 通过Nuget引入Unity程序集. PS:[版本:5.8.6] 2. 新建DIFactory类,用来读取Unity的配置文件并创建Unity容器,需要注意的是DIFacto ...

  2. 基于spring注解AOP的异常处理

    一.前言 项目刚刚开发的时候,并没有做好充足的准备.开发到一定程度的时候才会想到还有一些问题没有解决.就比如今天我要说的一个问题:异常的处理.写程序的时候一般都会通过try...catch...fin ...

  3. Spring基于AOP的事务管理

                                  Spring基于AOP的事务管理 事务 事务是一系列动作,这一系列动作综合在一起组成一个完整的工作单元,如果有任何一个动作执行失败,那么事务 ...

  4. 学习AOP之透过Spring的Ioc理解Advisor

    花了几天时间来学习Spring,突然明白一个问题,就是看书不能让人理解Spring,一方面要结合使用场景,另一方面要阅读源代码,这种方式理解起来事半功倍.那看书有什么用呢?主要还是扩展视野,毕竟书是别 ...

  5. 学习AOP之深入一点Spring Aop

    上一篇<学习AOP之认识一下SpringAOP>中大体的了解了代理.动态代理及SpringAop的知识.因为写的篇幅长了点所以还是再写一篇吧.接下来开始深入一点Spring aop的一些实 ...

  6. 学习AOP之认识一下Spring AOP

    心碎之事 要说知道AOP这个词倒是很久很久以前了,但是直到今天我也不敢说非常的理解它,其中的各种概念即抽象又太拗口. 在几次面试中都被问及AOP,但是真的没有答上来,或者都在面上,这给面试官的感觉就是 ...

  7. .Net中的AOP系列之构建一个汽车租赁应用

    返回<.Net中的AOP>系列学习总目录 本篇目录 开始一个新项目 没有AOP的生活 变更的代价 使用AOP重构 本系列的源码本人已托管于Coding上:点击查看. 本系列的实验环境:VS ...

  8. .NET里简易实现AOP

    .NET里简易实现AOP 前言 在MVC的过滤器章节中对于过滤器的使用就是AOP的一个实现了吧,时常在工作学习中遇到AOP对于它的运用可以说是很熟练了,就是没想过如果自己来实现的话是怎么实现的,性子比 ...

  9. 在.Net中实现自己的简易AOP

    RealProxy基本代理类 RealProxy类提供代理的基本功能.这个类中有一个GetTransparentProxy方法,此方法返回当前代理实例的透明代理.这是我们AOP实现的主要依赖. 新建一 ...

随机推荐

  1. java基础总结(1)--深入理解基本数据类型

    深入理解java数据类型 java是一种强类型语言,这就意味着必须为每一个声明变量声明一种类型.在java中,一共有8种数据类型,其中4种整型,2种浮点类型,1种字符类型和一种表示真值的boolean ...

  2. ganglia 服务端

    #!/bin/bash #配置参数 serverIP=192.168.1.16 network=ens32 #关闭selinux setenforce sed -i 's/SELINUX=enforc ...

  3. 如何在SQL Server 2008下轻松调试T-SQL语句和存储过程

    一.回顾早期的SQL SERVER版本:早在SQL Server 2000时代,查询分析器的功能还很简陋,远不如VS那么强大.到SQL Server 2005时代,代码高亮.SQL优化等功能逐渐加强, ...

  4. java.lang.IllegalArgumentException: A null value cannot be assigned to a primitive type

    今天做项目测试接口,查询数据时出现以下错误,记录一下. 查询语句和错误信息: 实体类属性 原因是 由于字段 total和receive 在实体类中使用的是 int类型,但是数据库中查询出来的数据为nu ...

  5. 【日常错误】Could not initialize class org.hibernate.validator.internal.engine.ConfigurationImpl

    最近在用spring-boot编写一个Lucene项目,中间用到了redis,引用了spring-boot-starter-data-redis,在eclipse中用外部Tomcat启动项目一切正常, ...

  6. Ubuntu&Mac下使用alias简化日常操作

    alias 在Linux系统中用来给指令起别名,用来简化很长的指令. 用法很简单: alias : 查看当前所有别名 alias tmstart = "$CATALINA_HOME/bin/ ...

  7. 单核苷酸多态性SNP(single nucleotide polymorphism)

    定义 主要指基因组水平上由单个核苷酸的变异所引起的 DNA 序列多态性. 在基因组水平上由单个核苷酸的变异所引起的DNA序列多态性.即:在不同个体的同一条染色体或同一位点的核苷酸序列中,绝大多数核苷酸 ...

  8. 简单ORM的实现

    简单的orm实现 我们在使用各种框架的时候,关于数据库这方面的使用,框架给我们提供了很好的封装,这个就是orm 关系映射 orm的底层无非就是做了关系映射 数据库的表(table) --> 类( ...

  9. iOS 一些struct类型的NSLog输出格式

    https://my.oschina.net/sayonala/blog/215910 我们经常会输出一些坐标尺寸信息之类的,比如view的frame,是CGRect类型的,用frame.oringi ...

  10. 快速理解spark-on-k8s中的external-shuffle-service

    [摘要] external-shuffle-service是Spark里面一个重要的特性,有了它后,executor可以在不同的stage阶段动态改变数量,大大提升集群资源利用率.但是这个特性当前在k ...