本文关注以下方面(环境为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. how to disabled iframe page open new window / new tab

    how to disabled iframe page open new window / new tab 禁用 iframe 中的页面打开新页面 <!DOCTYPE html> < ...

  2. nowcoder 203A Knight(贪心+打表)

    题目链接 题目描述 有一张无限大的棋盘,你要将马从(0,0)移到(n,m). 每一步中,如果马在(x,y),你可以将它移动到(x+1,y+2),(x+1,y-2),(x-1,y+2),(x-1,y-2 ...

  3. ansible操作(一)

    ansible晋级操作之ad-hoc命令 所谓的ad-hoc命令! 如果我们敲入一些命令去比较快的完成一些事情,而不需要将这些执行的命令特别保存下来, 这样的命令就叫做 ad-hoc 命令.Ansib ...

  4. c++11 模板的别名

    c++11 模板的别名 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #inclu ...

  5. tarjan解决路径询问问题

    好久没更新了,就更一篇普及组内容好了. 首先我们考虑如何用tarjan离线求出lca,伪代码大致如下: def tarjan(x): 将x标记为已访问 for c in x的孩子: tarjan(c) ...

  6. win7下解决烦人的管理员权限问题

    禁不住诱惑,用上win7了.可是,对system下的文件进行编辑时候,老是碰到什么必须拥有管理员权限才能进行操作,删除文件或者文件夹也遇到一样的问题.我就纳闷了,我不就是超级管理员吗?我怎么就没有权限 ...

  7. MVP, MVVM In Android

    MVP, MVVM In Android(新手必看)安卓MVP的理解,看完你就会用mvp了 - zq019的博客 - 博客频道 - CSDN.NEThttp://blog.csdn.net/zq019 ...

  8. MYSQL指定用户访问指定数据库

    1.使用navicat 1)首先使用root用户新建连接 2)新建mysql用户 3)点击权限,选择添加权限,出现MySQL中已存在的数据库列表,选择你要为该新建用户开放的数据库,此处选择“maiba ...

  9. java CPU 100% 排查(转载)

    一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原因都是出现了死循环. (友情提示:本博文章欢迎转载,但请注明出处:hankchen,http://www.blogjava.net/hank ...

  10. R语言的ARIMA模型预测

    R通过RODBC连接数据库 stats包中的st函数建立时间序列 funitRoot包中的unitrootTest函数检验单位根 forecast包中的函数进行预测 差分用timeSeries包中di ...