本文关注以下方面(环境为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. 使用flex布局调换两个按钮的位置

    组件用的时antd的Modal组件,里面的按钮需要调换一下位置 今天发现用flex布局非常方便,代码如下: display: flex; justify-content: center; flex-f ...

  2. Asp.Net Core实现文件上传

    1. Asp.Net Core Mvc方式 public class UploadController : Controller { private IHostingEnvironment _host ...

  3. 如何规范 CSS 的命名和书写

    我开始学前端的时候也是对于规范问题头疼,后来看了网易的NEC规范,惊呼牛逼 NEC : 更好的CSS样式解决方案 只遵循横向顺序即可,先显示定位布局类属性,后盒模型等自身属性,最后是文本类及修饰类属性 ...

  4. jenkins+maven+Tomcat8实现热部署

    个人记录 公司使用jenkins实现代码自动更新并部署 采用jenkins安装方式为war包,版本为:2.138.3,启动方式为Tomcat启动jenkins, 该博客操作步骤有些地方进行简化,各位需 ...

  5. 题解 P3870 【[TJOI2009]开关】

    这个题我愣是交了好几遍没有过...... 后来@_皎月半洒花dalao告诉我说要^儿子节点的tag,然后就明白了...... 行吧,先上题面: 题目描述 现有N(2 ≤ N ≤ 100000)盏灯排成 ...

  6. MT【148】凸数列

    (2018浙江省赛13题) 设实数$x_1,x_2,\cdots,x_{2018}$满足$x_{n+1}^2\le x_nx_{n+2},(n=1,2,\cdots,2016)$和$\prod\lim ...

  7. AJAX实现无刷新登录

    最近学习了如何实现无刷新登录,大体的效果如下(界面比较丑,请自行忽略....): 点击登录按钮时弹出登录窗口,输入正确的用户名密码后点击登录则登录窗口关闭,状态改为当前用户名. 第一步: 首先弹出窗口 ...

  8. 【转】rt-thread的位图调度算法分析

    序言 期待读者 本文期待读者有C语言编程基础,后文中要分析代码,对其中的一些C语言中的简单语句不会介绍,但是并不要求读者有过多的C基础,比如指针和链表等不会要求太多,后面在分析代码时,会附带地介绍相关 ...

  9. 【BZOJ4916】神犇和蒟蒻 解题报告

    [BZOJ4916]神犇和蒟蒻 Description 很久很久以前,有一群神犇叫sk和ypl和ssr和hjh和hgr和gjs和yay和xj和zwl和dcx和lyy和dtz和hy和xfz和myh和yw ...

  10. 【bzoj4011】 HNOI2015—落忆枫音

    http://www.lydsy.com/JudgeOnline/problem.php?id=4011 (题目链接) 题意 给出一个拓扑图,再加入一条边,问树形图个数. Solution 右转题解→ ...