您的位置:首页 > 移动开发 > Unity3D

使用Unity 实现 AOP

2009-04-28 17:22 363 查看
前提

引用以下文件

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接口

[code]
[code] public  interface IOutput {


void Output(int x);


}

[/code]
[/code]
实现效果

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

[code]
[code] class OutputImplement2 : IOutput {


public void Output(int x) {


Console.WriteLine("output:{0}", x);


}


}

[/code]
[/code]
调用它即在Main函数中

[code]
[code] var op2=new OutputImplement2();


op2.Output(22);

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





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

定义处理代码

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

[code]
[code] public class MyHandler : ICallHandler {


     public int Order { get; set;}//这是ICallHandler的成员,表示执行顺序


public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) {


Console.WriteLine("方法名: {0}", input.MethodBase.Name);


Console.WriteLine("参数:");


for (var i = 0; i < input.Arguments.Count; i++) {


Console.WriteLine("{0}: {1}", input.Arguments.ParameterName(i), input.Arguments[i]);


}


Console.WriteLine("执行");


//这之前插入方法执行前的处理


var retvalue = getNext()(input, getNext);//在这里执行方法


//这之后插入方法执行后的处理


Console.WriteLine("完成");


return retvalue;


}


}

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

1.通过代码直接关联

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

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

[code]
[code] public class MyHandlerAttribute : HandlerAttribute {


public override ICallHandler CreateHandler(IUnityContainer container) {


return new MyHandler();//返回MyHandler


}


}

[/code]
[/code]
然后在IOutput的实现中使用如下代码:

[code]
[code] [MyHandler]


class OutputImplement1 : IOutput {


 public void Output(int x) {


Console.WriteLine("重典执行此方法输出:{0}", x);


}


}

[/code]
[/code]
这里靠此Attribute就将二者关联了起来

现在执行处写:

[code]
[code] varcontainer1 = new UnityContainer()


.AddNewExtension<Interception>()


.RegisterType<IOutput, OutputImplement1>();//声明UnityContainer并注册IOutput


container1


.Configure<Interception>()


.SetInterceptorFor<IOutput>(new InterfaceInterceptor());


 var op1 =container1.Resolve<IOutput>();


op1.Output(11);//调用

[/code]
[/code]
That’s all OK.

2.用配置文件处理

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

[code]
[code] class OutputImplement2 : IOutput {


public void Output(int x) {


Console.WriteLine("重典执行此方法输出:{0}", x);


}


}

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

[code]
[code] <?xml version="1.0" encoding="utf-8" ?>


<configuration>


<configSections>


<section name="unity"


type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,


Microsoft.Practices.Unity.Configuration, Version=1.2.0.0,


Culture=neutral, PublicKeyToken=31bf3856ad364e35" />


</configSections>


<unity>


<typeAliases>


<typeAlias alias="singleton"


type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity" />


<typeAlias alias="transparentProxy"


type="Microsoft.Practices.Unity.InterceptionExtension.TransparentProxyInterceptor, Microsoft.Practices.Unity.Interception" />


<typeAlias alias="typeMatchingRule"


type="Microsoft.Practices.Unity.InterceptionExtension.TypeMatchingRule, Microsoft.Practices.Unity.Interception"/>


<typeAlias alias="interception"


type="Microsoft.Practices.Unity.InterceptionExtension.Interception, Microsoft.Practices.Unity.Interception"/>


<typeAlias alias="IOutput" type="ConsoleApplication1.IOutput, ConsoleApplication1" />


<typeAlias alias="MyHandler" type="ConsoleApplication1.MyHandler, ConsoleApplication1" />


<typeAlias alias="OutputImplement2" type="ConsoleApplication1.OutputImplement2, ConsoleApplication1" />


</typeAliases>


<containers>


<container name="DefContainer">


<types>


<type type="IOutput" mapTo="OutputImplement2" name="">


<lifetime type="singleton" />


</type>


</types>


</container>


</containers>


</unity>


</configuration>

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

[code]
[code] var container2 = new UnityContainer().AddNewExtension<Interception>();//声明UnityContainer


var map = new ExeConfigurationFileMap {ExeConfigFilename = "Unity.xml"};//使用此配置文件


var config


= ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);


var section


= (UnityConfigurationSection)config.GetSection("unity");//读取配置文件节点


section.Containers["DefContainer"].Configure(container2);


container2.Configure<Interception>()


.SetDefaultInterceptorFor<IOutput>(new TransparentProxyInterceptor())


.AddPolicy("LogMethod")


.AddMatchingRule(new TypeMatchingRule("IOutput"))


.AddCallHandler(typeof(MyHandler));


var op2 = container2.Resolve<IOutput>();


op2.Output(22);//调用

[/code]
[/code]

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





代码下载:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: