Unity 3(二):Unity在AOP方面的应用
本文关注以下方面(环境为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方面的应用的更多相关文章
- Unity应用架构设计(12)——AOP思想的实践
想象一下,当程序所有的业务逻辑都完成的时候,你可能还来不及喘口气,紧张的测试即将来临.你的Boss告诉你,虽然程序没问题,但某些方法为什么执行这么慢,性能堪忧.领会了Boss的意图之后,漫长的排查问题 ...
- 漫话Unity(二)
三.Unity编辑器介绍 Unity是一个商业级的3d游戏引擎.一个引擎的专业程度事实上并非体如今它多么牛b 的次世代效果,说实话那些效果即便你会用也不敢用.由于没有哪个手机是次世代的. 游戏引擎的专 ...
- Unity 依赖注入容器的AOP扩展
使用EntLib\PIAB Unity 实现动态代理 using System; using Unity; using Unity.Interception; using Unity.Intercep ...
- Unity学习笔记(二)——第一个Unity项目Hello Unity
保留版权,转载请注明出处:http://blog.csdn.net/panjunbiao/article/details/9318811 在这一篇文章里,参照宣雨松的<Unity 3D游戏开发& ...
- 【Unity Shader】Unity Chan的卡通材质
写在前面 时隔两个月我终于来更新博客了,之前一直在学东西,做一些项目,感觉没什么可以分享的就一直没写.本来之前打算写云彩渲染或是Compute Shader的,觉得时间比较长所以打算先写个简单的. 今 ...
- 【Unity编程】Unity中关于四元数的API详解
本文为博主原创文章,欢迎转载,请保留出处:http://blog.csdn.net/andrewfan Unity中关于四元数的API详解 Quaternion类 Quaternion(四元数)用于计 ...
- 从Unity中的Attribute到AOP(二)
上一篇文章我们初步了解了一下Attributes的含义,并且使用系统自带的Attributes写了点代码.在进一步解剖我们的代码之前,我觉得有个概念可能需要巩固一下:什么是元数据? 我们知道C#代码会 ...
- 依賴注入入門——Unity(二)
參考博客文章http://www.cnblogs.com/kebixisimba/category/130432.html http://www.cnblogs.com/qqlin/tag/Unity ...
- Gvr SDK for Unity 分析(二)
前言 关于google vr sdk的具体使用,传送门 Gvr SDK for Unity 分析(一) Google Daydream平台已经整合进Google VR SDK 本文环境:Unity5. ...
- WPF PRISM开发入门二(Unity依赖注入容器使用)
这篇博客将通过一个控制台程序简单了解下PRISM下Unity依赖注入容器的使用.我已经创建了一个例子,通过一个控制台程序进行加减乘除运算,项目当中将输入输出等都用接口封装后,结构如下: 当前代码可以点 ...
随机推荐
- Django知识总汇
基础 Django基础 Django基本命令 model系统 ORM基础 ORM字段和参数 ORM对数据库操作 ORM中介模型 ORM之其他骚操作 templates系统 模板语言 views系统 视 ...
- JAVA ACM 基础
java ACM Java做ACM-ICPC的特点: (1) 在一般比赛中,Java程序会有额外的时间和空间,而实际上经过实验,在执行计算密集任务的时候Java并不比C/C++慢多少,只是IO操作较慢 ...
- es各类SearchType的意思
元素 含义 QUERY_THEN_FETCH 查询是针对所有的块执行的,但返回的是足够的信息,而不是文档内容(Document).结果会被排序和分级,基于此,只有相关的块的文档对象会被返回.由于被取到 ...
- VUE开发一个图片轮播的组件
完成效果图如下: vue开发的思路主要是数据绑定,代码如下: <template> <div ref="root" style="user-select ...
- 关于Swift中的泛函数find的问题
对于一个数组Array,我们往往需要判断其是否包含某个子项,又或者要查找某个子项是否在这个数组中. 假设有这样一个包含坐标的数组 var pointArray:[CGPoint] = [CGPoint ...
- BZOJ 3295 动态逆序对 | CDQ分治
BZOJ 3295 动态逆序对 这道题和三维偏序很类似.某个元素加入后产生的贡献 = time更小.pos更小.val更大的元素个数 + time更小.pos更大.val更小的元素个数. 分别用类似C ...
- Active Directory PowerShell模块收集AD信息
0x00 前言简介 Microsoft为Windows Server 2008 R2(以及更高版本)提供了多个Active Directory PowerShell cmdlet,这大大简化了以前需要 ...
- MyBatis.1入门篇
一:简介 MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动.创建connection.创建statem ...
- Android Studio之BuildConfig类
https://blog.csdn.net/lvxiangan/article/details/71601451 Android Studio开发中,把一个module输出打包为jar文件,我们会发现 ...
- 【学习笔记】BEST定理
害怕忘记简单写一点: 无向图的生成树计数:https://www.cnblogs.com/zj75211/p/8039443.html (*ZJ学长 ORZ ) 有向图的欧拉回路计数:https: ...