本文关注以下方面(环境为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. 使用pyquery是遇到的一个403的问题

    在网上爬虫时,本地windows下运行pyquery代码正常,但是在linux下运行时一直报错 403 Forbidden.刚开始的代码如下 from pyquery import PyQuery a ...

  2. 【大数据】MapTask并行度和切片机制

    一. MapTask并行度决定机制 maptask的并行度决定map阶段的任务处理并发度,进而影响到整个job的处理速度 那么,mapTask并行实例是否越多越好呢?其并行度又是如何决定呢? 1.1 ...

  3. 转:关于python文件操作大全

    转自:http://www.cnblogs.com/rollenholt/archive/2012/04/23/2466179.html python中对文件.文件夹(文件操作函数)的操作需要涉及到o ...

  4. 导入eclipse工程到Android Studio中

    ref:从 Eclipse 迁移至 Android Studio | Android Studiohttps://developer.android.com/studio/intro/migrate. ...

  5. Java类编译、加载、和执行机制

    Java类编译.加载.和执行机制 标签: java 类加载 类编译 类执行 机制 0.前言 个人认为,对于JVM的理解,主要是两大方面内容: Java类的编译.加载和执行. JVM的内存管理和垃圾回收 ...

  6. 旧题新做:从idy的视角看数据结构

    “今天你不写总结……!!!” 额…… 还是讲我的吧.这些考试都是idy出的题. 20170121:DFS序. ST表.线段树练习 这是第一次考数据结构. Problem 1. setsum 1 sec ...

  7. 【agc003D】Anticube

    Portal --> agc003D Description 给你\(n\)个数,要从里面选出最多的数满足这些选出来的数中任意两个数的乘积都不是立方数 Solution (为什么感觉最近这种解法 ...

  8. golang 安装一个项目下的所有依赖

    go get -v ./...

  9. 【题解】Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths Codeforces 741D DSU on Tree

    Prelude 很好的模板题. 传送到Codeforces:(* ̄3 ̄)╭ Solution 首先要会DSU on Tree,不会的看这里:(❤ ω ❤). 众所周知DSU on Tree是可以用来处 ...

  10. docker中实现服务日志轮转

    问题背景 通常我们一个完整的应用镜像有两部分组成,一个是运行时环境,一个是应用程序.我们以php应用为例,一个完整的php应用需要包含openresty + php两个服务来配置运行时环境,然后再加上 ...