首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

请问unity1.2的aop配置

2012-12-15 
请教unity1.2的aop配置如题,我在网上搜的例子都是在类的方法上增加标记,一定程度上降低了程序的灵活性.cla

请教unity1.2的aop配置
如题,我在网上搜的例子都是在类的方法上增加标记,一定程度上降低了程序的灵活性.

class Program
{
    static void Main(string[] args)
    {
        var container1 = new UnityContainer().AddNewExtension<Interception>().RegisterType<IOutput, OutputImplement1>();//声明UnityContainer并注册IOutput   
        container1.Configure<Interception>().SetInterceptorFor<IOutput>(new InterfaceInterceptor());
        IOutput op1 = container1.Resolve<IOutput>();
        op1.Output(11);//调用
        Console.ReadLine();
    }
}
public interface IOutput
{
    void Output(int x);
}
[MyHandler]
public class OutputImplement1 : IOutput
{
    public void Output(int x)
    {
        Console.WriteLine("执行此方法输出:{0}", x);
        throw new Exception("这里抛个异常出来");
    }
}
public class MyHandler : ICallHandler
{
    public int Order { get; set; }//这是ICallHandler的成员,表示执行顺序   
    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        //这之前插入方法执行前的处理  
        Console.WriteLine("执行前");
        IMethodReturn retvalue = getNext()(input, getNext);//在这里执行方法  
        if (retvalue.Exception == null) // retvalue.Exception=null说明函数执行时没有抛出异常
        {
            Console.WriteLine("执行成功,无异常");
        }
        else
        {
            Console.WriteLine("Exxxxxx:" + retvalue.Exception.Message);
            retvalue.Exception = null; // 将retvalue.Exception设为null表示异常已经被处理过了,
                                       // 如果不把retvalue.Exception设为null,Unity会再次抛出此异常。
        }
        //这之后插入方法执行后的处理  
        Console.WriteLine("完成");
        return retvalue;
    }
}
public class MyHandlerAttribute : HandlerAttribute
{
    public override ICallHandler CreateHandler(IUnityContainer container)
    {
        return new MyHandler();//返回MyHandler   
    }
}
=======================================================================================
能否使用配置代替[MyHandler]标记...



[解决办法]
使用Unity 实现 AOP 前提

引用以下文件

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方法执行前或执行后注入其它执行过程即最后形成的结果可能是:


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

 

定义处理代码

这里我们先定义一段处理方法的代码,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这时我们看到的结果就是:



[解决办法]
感请楼上的兄弟.

一定要定义MyHandler吗??能否把下面的显式注册改为直接配置?

var container2 = new UnityContainer().AddNewExtension<Interception>();
var map = new ExeConfigurationFileMap {ExeConfigFilename = "Unity.xml


container2.Configure<Interception>()
.SetDefaultInterceptorFor<IOutput>(new TransparentProxyInterceptor())
.AddPolicy("LogMethod")   
.AddMatchingRule(new TypeMatchingRule("IOutput"))   
.AddCallHandler(typeof(MyHandler));   

------解决方案--------------------


那个logMethod是什么类? 
[解决办法]
ding
[解决办法]
 ding
[解决办法]
ding
[解决办法]
尚未解决,再顶!
[解决办法]
没有找到办法将policy和unity的配置文件整合到一起,只好分别加载.

unity.config片段
 <extensions>
          <add type="Interception" />
        </extensions>
           <extensionConfig>
          <add name="Interception" type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationElement, Microsoft.Practices.Unity.Interception.Configuration">
            <interceptors>
              <interceptor type="VirtualMethod">
                <key type="SysUserService" name="SysUserService" />
              </interceptor> 
            </interceptors>
          </add>
        </extensionConfig>   
PolicyInjection.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="policyInjection" type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration.PolicyInjectionSettings, Microsoft.Practices.EnterpriseLibrary.PolicyInjection" />
  </configSections>
  <policyInjection>
    <policies>
      <add name="Policy">
        <matchingRules>
          <add type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.MemberNameMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection"
            name="Member Name Matching Rule">
            <matches>
              <add match="*" />
               <!--
               <add match="Process*" ignoreCase="false" />
               <add match="Output*" ignoreCase="false" />
               -->
            </matches>
          </add>
        </matchingRules>
        <handlers>


          <add  order="0" type="Bal.common.TransactionHandler, Bal" name="TransactionHandler" />
        </handlers>
      </add>
    </policies>
  </policyInjection>

</configuration>
[解决办法]
楼主,后面那个Aop拦截的配置调通了吗?
我设置的时候总是无法加载extensionConfig 这个节点文件
请问是什么原因哦?

热点排行