本文关注以下方面(环境为VS2012、.Net Framework 4.5以及Unity 3):

  • AOP简介;
  • Interception using Unity示例
  • 配置文件示例

一、AOP简介

  AOP为Aspect-Oriented Programming的缩写,意为"面向切面(方面)编程",按维基百科的解释是"AOP is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns" (http://en.wikipedia.org/wiki/Aspect-oriented_programming)。

  通俗的理解就是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术,我们可以理解为在一个服务的流程中,插入与该服务的业务逻辑无关的系统服务逻辑(操作前或操作后),如日志记录、安全认证、性能检测等等。

二、Interception using Unity示例

  本示例中主要用于展示如何应用Unity实现编程的Interception,更多内容请阅读http://msdn.microsoft.com/en-us/library/dn178466.aspx

  还是以一个简单的日志记录程序为例

  Console程序如下(以Log为例)

    interface ILog
{
void Log(string message);
}
    class ConsoleLog : ILog
{
public void Log(string message)
{
Console.WriteLine(message);
}
}

  下面我们编写一个切入的用于记录日志的类,当然首先要引入相应的命名空间,Unity Interception Extension可以通过NuGet获取

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Practices.Unity.InterceptionExtension; namespace Demo
{
class LoggingInterceptionBehavior : IInterceptionBehavior
{
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
// Before invoking the method on the original target.
WriteLog(String.Format("Invoking method {0} at {1}",
input.MethodBase,
DateTime.Now.ToLongTimeString())); // Invoke the next behavior in the chain.
var result = getNext()(input, getNext); // After invoking the method on the original target.
if (result.Exception != null)
{
WriteLog(String.Format("Method {0} threw exception {1} at {2}",
input.MethodBase,
result.Exception.Message,
DateTime.Now.ToLongTimeString()));
}
else
{
WriteLog(String.Format("Method {0} returned {1} at {2}",
input.MethodBase,
result.ReturnValue,
DateTime.Now.ToLongTimeString()));
} return result;
} public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
} public bool WillExecute
{
get { return true; }
} private void WriteLog(string message)
{
Console.WriteLine(message);
}
}
}

  为了方便观察多个切入,我们在定义一个PerformanceInterceptionBehavior

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Practices.Unity.InterceptionExtension; namespace PCT.Unity.DIWithUntiy
{
class PerformanceInterceptionBehavior : IInterceptionBehavior
{
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Reset();
stopwatch.Start(); // Invoke the next behavior in the chain.
var result = getNext()(input, getNext); // After invoking the method on the original target.
if (result.Exception != null)
{
WriteLog(String.Format("Method {0} threw exception {1} at {2}",
input.MethodBase,
result.Exception.Message,
DateTime.Now.ToLongTimeString()));
}
else
{
stopwatch.Stop();
WriteLog(String.Format("Method {0} executed {1}", input.MethodBase, stopwatch.Elapsed));
} return result;
} public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
} public bool WillExecute
{
get { return true; }
} private void WriteLog(string message)
{
Console.WriteLine(message);
}
}
}

  最终控制台的代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.InterceptionExtension; namespace PCT.Unity.DIWithUntiy
{
class Program
{
static void Main(string[] args)
{
var container = new UnityContainer();
container.AddNewExtension<Interception>();
container.RegisterType<ILog, ConsoleLog>(
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<LoggingInterceptionBehavior>(),
new InterceptionBehavior<PerformanceInterceptionBehavior>()); var logger = container.Resolve<ILog>();
logger.Log("Hello, Unity Framework!");
Console.ReadKey();
}
}
}

  运行结果如下

  如果我们把代码改成如下

container.RegisterType<ILog, ConsoleLog>(
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<PerformanceInterceptionBehavior>(),
new InterceptionBehavior<LoggingInterceptionBehavior>());

  再次运行

  是不是发现了什么,对,切入的顺序不同,最终执行的顺序也不同。

三、配置文件示例

  控制台代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using Microsoft.Practices.Unity.InterceptionExtension; namespace PCT.Unity.DIWithUntiy
{
class Program
{
static void Main(string[] args)
{
var container = new UnityContainer();
//container.AddNewExtension<Interception>();
//container.RegisterType<ILog, ConsoleLog>(
// new Interceptor<InterfaceInterceptor>(),
// new InterceptionBehavior<PerformanceInterceptionBehavior>(),
// new InterceptionBehavior<LoggingInterceptionBehavior>()); container.LoadConfiguration(); var logger = container.Resolve<ILog>();
logger.Log("Hello, Unity Framework!");
Console.ReadKey();
}
}
}

  配置文件

<?xml version="1.0" encoding="utf-8" ?>
<configuration> <configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>
</configSections> <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension,
Microsoft.Practices.Unity.Interception.Configuration" />
<alias alias="ILog" type="PCT.Unity.DIWithUntiy.ILog"/>
<alias alias="ConsoleLog" type="PCT.Unity.DIWithUntiy.ConsoleLog"/>
<alias alias="PerformanceInterceptionBehavior" type="PCT.Unity.DIWithUntiy.PerformanceInterceptionBehavior"/>
<alias alias="LoggingInterceptionBehavior" type="PCT.Unity.DIWithUntiy.LoggingInterceptionBehavior"/>
<assembly name="PCT.Unity.DIWithUntiy" />
<namespace name="PCT.Unity.DIWithUntiy" />
<container>
<extension type="Interception"/>
<register type="ILog" mapTo="ConsoleLog">
<interceptor type="InterfaceInterceptor"/>
<interceptionBehavior type="LoggingInterceptionBehavior" />
<interceptionBehavior type="PerformanceInterceptionBehavior" />
</register>
</container>
</unity> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>

Unity 3(二):Unity在AOP方面的应用的更多相关文章

  1. Unity应用架构设计(12)——AOP思想的实践

    想象一下,当程序所有的业务逻辑都完成的时候,你可能还来不及喘口气,紧张的测试即将来临.你的Boss告诉你,虽然程序没问题,但某些方法为什么执行这么慢,性能堪忧.领会了Boss的意图之后,漫长的排查问题 ...

  2. 漫话Unity(二)

    三.Unity编辑器介绍 Unity是一个商业级的3d游戏引擎.一个引擎的专业程度事实上并非体如今它多么牛b 的次世代效果,说实话那些效果即便你会用也不敢用.由于没有哪个手机是次世代的. 游戏引擎的专 ...

  3. Unity 依赖注入容器的AOP扩展

    使用EntLib\PIAB Unity 实现动态代理 using System; using Unity; using Unity.Interception; using Unity.Intercep ...

  4. Unity学习笔记(二)——第一个Unity项目Hello Unity

    保留版权,转载请注明出处:http://blog.csdn.net/panjunbiao/article/details/9318811 在这一篇文章里,参照宣雨松的<Unity 3D游戏开发& ...

  5. 【Unity Shader】Unity Chan的卡通材质

    写在前面 时隔两个月我终于来更新博客了,之前一直在学东西,做一些项目,感觉没什么可以分享的就一直没写.本来之前打算写云彩渲染或是Compute Shader的,觉得时间比较长所以打算先写个简单的. 今 ...

  6. 【Unity编程】Unity中关于四元数的API详解

    本文为博主原创文章,欢迎转载,请保留出处:http://blog.csdn.net/andrewfan Unity中关于四元数的API详解 Quaternion类 Quaternion(四元数)用于计 ...

  7. 从Unity中的Attribute到AOP(二)

    上一篇文章我们初步了解了一下Attributes的含义,并且使用系统自带的Attributes写了点代码.在进一步解剖我们的代码之前,我觉得有个概念可能需要巩固一下:什么是元数据? 我们知道C#代码会 ...

  8. 依賴注入入門——Unity(二)

    參考博客文章http://www.cnblogs.com/kebixisimba/category/130432.html http://www.cnblogs.com/qqlin/tag/Unity ...

  9. Gvr SDK for Unity 分析(二)

    前言 关于google vr sdk的具体使用,传送门 Gvr SDK for Unity 分析(一) Google Daydream平台已经整合进Google VR SDK 本文环境:Unity5. ...

  10. WPF PRISM开发入门二(Unity依赖注入容器使用)

    这篇博客将通过一个控制台程序简单了解下PRISM下Unity依赖注入容器的使用.我已经创建了一个例子,通过一个控制台程序进行加减乘除运算,项目当中将输入输出等都用接口封装后,结构如下: 当前代码可以点 ...

随机推荐

  1. 刷新dbgrid 而不失去当前行位置

    我们有一个Delphi的数据库应用程序,上面有个DBGrid和一个数据集: DBGrid是用来显示来自数据集(查询或表)的数据,根据设计,当您调用已经打开的数据集的Refresh方 法(例如使用DBN ...

  2. spring的jar包以及相关的API文档的下载方式

    转自:http://blog.csdn.net/yuexianchang/article/details/53583327 侵删 感谢原创 首先是进入官网:https://spring.io/ 如图所 ...

  3. AtCoder Grand Contest 029 翻车记

    A:对于每个B,会和其右边的每个W交换一次. #include<iostream> #include<cstdio> #include<cmath> #includ ...

  4. 洛谷 P2389 电脑班的裁员 解题报告

    题意: 给定一段长为N的序列,选取其中的至多M段使这些子段和最大. 当N=1000时,我们可以采用动态规划解法 令\(dp[i][j][k]\)代表当前选至位置\(i\)处于第\(j\)段当前是否选取 ...

  5. java堆溢出

    java堆是用来存储对象实例的:只要不断创建对象,GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,当对象数量达到最大堆的容量限制的时候就会产生内存溢出异常.异常对战信息为OutOf ...

  6. BZOJ4732. [清华集训2016]数据交互(树链剖分+线段树+multiset)

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4732 题解 首先,一个比较显然的结论是:对于一棵有根树上的两条链 \((x_1, y_1 ...

  7. C#线程篇---让你知道什么是线程(1)

    线程线程,进程进程,到底什么是线程,什么是熟练多线程编程? 今天来和大家一起讨论讨论线程基础,让大家知道线程的基本构造. 说线程之前,先要了解下进程,这个可不能不知道. 什么是进程? Microsof ...

  8. Java基础-程序流程控制第二弹(循环结构)

    Java基础-程序流程控制第二弹(循环结构) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 流程控制有三种基本结构:顺序结构,选择结构和循环结构.一个脚本就是顺序结构执行的,选择结 ...

  9. 即时通信系统Openfire分析之二:主干程序分析

    引言 宇宙大爆炸,于是开始了万物生衍,从一个连人渣都还没有的时代,一步步进化到如今的花花世界. 然而沧海桑田,一百多亿年过去了…. 好复杂,但程序就简单多了,main()函数运行,敲个回车,一行Hel ...

  10. bzoj千题计划132:bzoj1189: [HNOI2007]紧急疏散evacuate

    http://www.lydsy.com/JudgeOnline/problem.php?id=1189 二分答案 源点向人连边,流量为1 门拆为mid个点,同一个门的第j个点向第j+1个点连边,流量 ...