使用Unity 实现 AOP

简介: 前提 引用以下文件 Microsoft.Practices.ObjectBuilder2.dll Microsoft.Practices.Unity.dll Microsoft.Practices.

前提

引用以下文件

Microsoft.Practices.ObjectBuilder2.dll

Microsoft.Practices.Unity.dll

Microsoft.Practices.Unity.Configuration.dll

Microsoft.Practices.Unity.Interception.dll

Microsoft.Practices.Unity.Interception.Configuration.dll

Microsoft.Practices.Unity.StaticFactory.dll

可以从网站http://unity.codeplex.com/下载

本文中的实现类继承于IOutput接口

   1: public  interface IOutput {
   2:      void Output(int x);
   3: }

实现效果

我有两个方法可以输出字符串, 调用IOutput的实现类来输出的,如:

   1: class OutputImplement2 : IOutput {
   2:     public void Output(int x) {
   3:         Console.WriteLine("output:{0}", x);
   4:     }
   5: }

调用它即在Main函数中

   1: var op2=new OutputImplement2();
   2: op2.Output(22);

即可,而AOP的作用是通过其它代码,向op2.Output方法执行前或执行后注入其它执行过程即最后形成的结果可能是:

image

这里除了箭头所指的一句外其它的都是注入进去这个方法的。

 

定义处理代码

这里我们先定义一段处理方法的代码,Unity规定它是ICallHandler的一个实现

   1: public class MyHandler : ICallHandler {
   2:     public int Order { get; set; }//这是ICallHandler的成员,表示执行顺序
   3:     public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) {
   4:         Console.WriteLine("方法名: {0}", input.MethodBase.Name);
   5:         Console.WriteLine("参数:");
   6:         for (var i = 0; i < input.Arguments.Count; i++) {
   7:             Console.WriteLine("{0}: {1}", input.Arguments.ParameterName(i), input.Arguments[i]);
   8:         }
   9:         Console.WriteLine("执行");
  10:         //这之前插入方法执行前的处理
  11:         var retvalue = getNext()(input, getNext);//在这里执行方法
  12:         //这之后插入方法执行后的处理
  13:         Console.WriteLine("完成");
  14:         return retvalue;
  15:     }
  16: }

好,下面我们来看看怎么把MyHandler与IOutput关联起来,大体有2种方法

1.通过代码直接关联

这种实现方式比较“硬”。

它是利用Atrribute来实现这种关联的,首先,先建一个Attribute。

   1: public class MyHandlerAttribute : HandlerAttribute {
   2:     public override ICallHandler CreateHandler(IUnityContainer container) {
   3:         return new MyHandler();//返回MyHandler
   4:     }
   5: }

然后在IOutput的实现中使用如下代码:

   1: [MyHandler]
   2:  class OutputImplement1 : IOutput {
   3:      public void Output(int x) {
   4:          Console.WriteLine("重典执行此方法输出:{0}", x);
   5:      }
   6:  }

这里靠此Attribute就将二者关联了起来

现在执行处写:

   1: var container1 = new UnityContainer()
   2:     .AddNewExtension<Interception>()
   3:     .RegisterType<IOutput, OutputImplement1>();//声明UnityContainer并注册IOutput
   4: container1
   5:     .Configure<Interception>()
   6:     .SetInterceptorFor<IOutput>(new InterfaceInterceptor());
   7: var op1 = container1.Resolve<IOutput>();
   8: op1.Output(11);//调用

That’s all OK.

2.用配置文件处理

如果用配置文件的话就不用Attribute了,所以实现的类如下

   1: class OutputImplement2 : IOutput {
   2:     public void Output(int x) {
   3:         Console.WriteLine("重典执行此方法输出:{0}", x);
   4:     }
   5: }

这里不使用属性来标记了,而使用配置文件,我们建一个名为Unity.xml的配置文件(配置文件长,可以后看):

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:   <configSections>
   4:     <section name="unity"
   5:               type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
   6:                  Microsoft.Practices.Unity.Configuration, Version=1.2.0.0,
   7:                  Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
   8:   </configSections>
   9:   <unity>
  10:     <typeAliases>
  11:       <typeAlias alias="singleton"
  12:                  type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity" />
  13:       <typeAlias alias="transparentProxy"
  14:                  type="Microsoft.Practices.Unity.InterceptionExtension.TransparentProxyInterceptor, Microsoft.Practices.Unity.Interception" />
  15:       <typeAlias alias="typeMatchingRule"
  16:                  type="Microsoft.Practices.Unity.InterceptionExtension.TypeMatchingRule, Microsoft.Practices.Unity.Interception"/>
  17:       <typeAlias alias="interception"
  18:                  type="Microsoft.Practices.Unity.InterceptionExtension.Interception, Microsoft.Practices.Unity.Interception"/>
  19:       <typeAlias alias="IOutput" type="ConsoleApplication1.IOutput, ConsoleApplication1" />
  20:       <typeAlias alias="MyHandler" type="ConsoleApplication1.MyHandler, ConsoleApplication1" />
  21:       <typeAlias alias="OutputImplement2" type="ConsoleApplication1.OutputImplement2, ConsoleApplication1" />
  22:     </typeAliases>
  23:     <containers>
  24:       <container name="DefContainer">
  25:         <types>
  26:           <type type="IOutput" mapTo="OutputImplement2" name="">
  27:             <lifetime type="singleton" />
  28:           </type>
  29:         </types>
  30:       </container>
  31:     </containers>
  32:   </unity>
  33: </configuration>

最后我们来执行,要比第一种方法复杂一点:

   1: var container2 = new UnityContainer().AddNewExtension<Interception>();//声明UnityContainer
   2: var map = new ExeConfigurationFileMap {ExeConfigFilename = "Unity.xml"};//使用此配置文件
   3: var config
   4:    = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
   5: var section
   6:    = (UnityConfigurationSection)config.GetSection("unity");//读取配置文件节点
   7: section.Containers["DefContainer"].Configure(container2);
   8: container2.Configure<Interception>()
   9:    .SetDefaultInterceptorFor<IOutput>(new TransparentProxyInterceptor())
  10:    .AddPolicy("LogMethod")
  11:    .AddMatchingRule(new TypeMatchingRule("IOutput"))
  12:    .AddCallHandler(typeof(MyHandler));
  13: var op2 = container2.Resolve<IOutput>();
  14: op2.Output(22);//调用

 

OK这时我们看到的结果就是:

image

代码下载:

目录
打赏
0
0
0
0
1
分享
相关文章
基于Unity的AOP的符合基于角色的访问控制(RBAC)模型的通用权限设计
AOP的特性使得它非常适合用来设计类似权限控制的功能,这是本文的基础,如果想要了解AOP的实现,可以参考《动态织入的AOP实现》。 在基于角色的访问控制(RBAC)中,有三要素:用户、角色、任务(或操作)(User、Role、Task),其稳定性逐渐增强,两个关系,UserRole、RoleTas...
742 0
|
7月前
|
超实用!深度解析Unity引擎,手把手教你从零开始构建精美的2D平面冒险游戏,涵盖资源导入、角色控制与动画、碰撞检测等核心技巧,打造沉浸式游戏体验完全指南
【8月更文挑战第31天】本文是 Unity 2D 游戏开发的全面指南,手把手教你从零开始构建精美的平面冒险游戏。首先,通过 Unity Hub 创建 2D 项目并导入游戏资源。接着,编写 `PlayerController` 脚本来实现角色移动,并添加动画以增强视觉效果。最后,通过 Collider 2D 组件实现碰撞检测等游戏机制。每一步均展示 Unity 在 2D 游戏开发中的强大功能。
354 6
掌握这五大绝招,让您的Unity游戏瞬间加载完毕,从此告别漫长等待,大幅提升玩家首次体验的满意度与留存率!
【8月更文挑战第31天】游戏的加载时间是影响玩家初次体验的关键因素,特别是在移动设备上。本文介绍了几种常见的Unity游戏加载优化方法,包括资源的预加载与异步加载、使用AssetBundles管理动态资源、纹理和模型优化、合理利用缓存系统以及脚本优化。通过具体示例代码展示了如何实现异步加载场景,并提出了针对不同资源的优化策略。综合运用这些技术可以显著缩短加载时间,提升玩家满意度。
597 5
掌握Unity调试与测试的终极指南:从内置调试工具到自动化测试框架,全方位保障游戏品质不踩坑,打造流畅游戏体验的必备技能大揭秘!
【9月更文挑战第1天】在开发游戏时,Unity 引擎让创意变为现实。但软件开发中难免遇到 Bug,若不解决,将严重影响用户体验。调试与测试成为确保游戏质量的最后一道防线。本文介绍如何利用 Unity 的调试工具高效排查问题,并通过 Profiler 分析性能瓶颈。此外,Unity Test Framework 支持自动化测试,提高开发效率。结合单元测试与集成测试,确保游戏逻辑正确无误。对于在线游戏,还需进行压力测试以验证服务器稳定性。总之,调试与测试贯穿游戏开发全流程,确保最终作品既好玩又稳定。
293 4
【独家揭秘】那些让你的游戏瞬间鲜活起来的Unity UI动画技巧:从零开始打造动态按钮,提升玩家交互体验的绝招大公开!
【9月更文挑战第1天】在游戏开发领域,Unity 是最受欢迎的游戏引擎之一,其强大的跨平台发布能力和丰富的功能集让开发者能够迅速打造出高质量的游戏。优秀的 UI 设计对于游戏至关重要,尤其是在手游市场,出色的 UI 能给玩家留下深刻的第一印象。Unity 的 UGUI 系统提供了一整套解决方案,包括 Canvas、Image 和 Button 等组件,支持添加各种动画效果。
323 3
深度解析Unity游戏开发:从零构建可扩展与可维护的游戏架构,让你的游戏项目在模块化设计、脚本对象运用及状态模式处理中焕发新生,实现高效迭代与团队协作的完美平衡之路
【9月更文挑战第1天】游戏开发中的架构设计是项目成功的关键。良好的架构能提升开发效率并确保项目的长期可维护性和可扩展性。在使用Unity引擎时,合理的架构尤为重要。本文探讨了如何在Unity中实现可扩展且易维护的游戏架构,包括模块化设计、使用脚本对象管理数据、应用设计模式(如状态模式)及采用MVC/MVVM架构模式。通过这些方法,可以显著提高开发效率和游戏质量。例如,模块化设计将游戏拆分为独立模块。
319 3