好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Unity Application 学习

Unity Application 学习

Unity Application 学习笔记1 --初识

上一篇文章中间简要的写了一个 关于Autofac 东西。这两天看了一下关于Unity Application 的一些运用。

类似上一篇,写了几个相同的例子。

最开始时使用编码注入的方式。

代码如下:

  1   class   Program
   2       {
   3           static   void  Main( string  [] args)
   4           {
   5              Program p =  new   Program();
   6               //  p.Test3(); 
  7               p.Test4();
   8  
  9               Console.Read();
  10           }
  11  
 12           public   void   Test1()
  13           {
  14              UnityContainer container =  new   UnityContainer();
  15              container.RegisterType<ILog,PrintLoger> ();
  16              container.RegisterInstance(Console.Out); //  container.RegisterInstance<TextWriter>(Console.Out); 
 17              
 18              container.Resolve<ILog>().Create( "  this is test1  "  );
  19               //  将组件PrinterLoger注册到Ilog服务上,同时将Console.Out实例注册到TextWriter上
  20               //  请求Ilog服务的时候,会构造PrinterLoger组件的一个实例,使用参数Console.Out.构造成功。正常输出 
 21               container.Dispose();
  22           }
  23  
 24           public   void   Test2()
  25           {
  26              UnityContainer container =  new   UnityContainer();
  27              container.RegisterType<PrintLoger> ();
  28               container.RegisterInstance(Console.Out);
  29              container.Resolve<PrintLoger>().Create( "  this is test2  "  ); 
  30               container.Dispose();
  31  
 32               //  可正常输出。理解应该和autofac相同,我们将PrinterLoger 注册到容器内
  33               //  同时将组件的实例注册到TextWriter上
  34               //  Resolve PrinterLoger时,会构造请求该服务的组件的一个实例,调用其构造函数,传入Console.out参数,正常运行输出 
 35           }
  36  
 37           public   void   Test3()
  38           {
  39              UnityContainer container =  new   UnityContainer();
  40              container.RegisterType<Person> ();
  41              Person p= container.Resolve<Person> ();
  42               //  本例子只是为了说明一个类可以注册到自己身上,并且Reslove出来 
 43               container.Dispose();
  44           }
  45  
 46           public   void   Test4()
  47           {
  48               using  (UnityContainer container= new   UnityContainer())
  49               {
  50                  container.RegisterInstance<TextWriter> (Console.Out);
  51                  container.RegisterType<ILog, PrintLoger> ();
  52                   //  RegisterType可以 有两个泛型参数,From,To,其中,To是继承与From的
  53                   //  其实也就是将To组件注册到From服务上
  54                   //  当请求Reslove一个PrintLoger实例的时候,这个地方貌似不同于AutoFac的处理
  55                   //  能够使用该类去构造出一个实例(但前提是参数TextWriter可以Reslove出来) 
 56  
 57                  container.Resolve<PrintLoger>().Create( "  this is test4  " ); //  此处跟autofac 不同,不注册PrintLoger 也可以Resolve出来 todo cjt!!!!! 
 58               }
  59           }
  60  
 61  
 62      }

类和接口

     public   interface   ILog
    {
          void  Create( string  log,  params   object  [] paramters);
    }

      public   class   PrintLoger : ILog
    {
          protected  TextWriter TW {  get ;  set  ; }

          public   PrintLoger(TextWriter tw)
        {
              this .TW =  tw;
        }

          public   void  Create( string  log,  params   object  [] paramters)
        {
              if  (log ==  null  )
                  return  ;

              string  Log =  string  .Format(log, paramters);
            TW.WriteLine(Log);
        }
    }

     public   class   Person
    {
          public   string  ID {  get ;  set  ; }

          public   string  Name {  get ;  set  ; }
    } 

可以看出来,同Autofac的差别主要就在于Test4 上。在Autofac中,如果没有注册PrintLoger时,是无法Reslove 出一个实例的,而Unity Application 可以。

其他的,基本可以用相同的思维去理解。Register 将服务和组件 Map到一起(或者直接指定服务使用的组件实例)。

另外,Unity Application 还可以通过配置文件的方式,进行注入。

  1       class   Program
   2       {
   3           static   void  Main( string  [] args)
   4           {
   5              Program p =  new   Program();
   6               //  p.Test1(); 
  7               p.Test2();
   8               p.Test3();
   9  
 10               Console.ReadKey();
  11  
 12           }
  13  
 14           public   void   Test1()
  15           {
  16              IUnityContainer container =  new  UnityContainer().AddNewExtension<Interception> ();
  17              UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection( "  unity  "  );
  18               //  使用名称为Hello的Container,将文件中的配置读取初始化到Container中 
 19              section.Configure(container,  "  Hello  "  );
  20              IHello hello = container.Resolve<IHello> ();
  21               //  由于在Hello Container中,我们将IHello map 到 HelloB ,其将使用HelloB 进行构造实例
  22               //  实际上,这个地方运行时,是会报错的,Container会无法Reslove Ilog,我们并没有在该Container中队Ilog进行映射 
 23               hello.SayHello();
  24               container.Dispose();
  25           }
  26  
 27           public   void   Test2()
  28           {
  29              IUnityContainer container =  new   UnityContainer();
  30              UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection( "  unity  "  );
  31               //  该例子比较好理解,我们在配置文件中的Log Container 中配置了Ilog map 到 ClassPrintLog中
  32               //  请求ILog服务的时候,将会构造PrintLog实例,PrintLog是无参构造,Reslove成功 
 33              section.Configure(container,  "  Log  "  );
  34              container.Resolve<ILog>().Create( "  this is ilog  "  );
  35               container.Dispose();
  36           }
  37  
 38           public   void   Test3()
  39           {
  40              IUnityContainer container =  new   UnityContainer();
  41              UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection( "  unity  "  );
  42               //  在该节点的Container中,我们 将IHello map 到HelloA   将ILog map 到 PrintLog
  43               //  当请求Reslove IHello 时, 将会构造HelloA实例,然而发现HelloA 需要参数 ILog ,Container继续Reslove Ilog ,将会得到PrintLog实例
  44               //  如此,完成IHello hello=new HelloA(new PrintLog() ) 的构造
  45               //  Test1中和本例中都有一个不明白的地方,Unity 为什么会选中 含有参数的构造函数,而不使用无参的构造函数呢? Unity是如何选择构造函数的呢? 
 46              section.Configure(container,  "  SayHelloLog  "  );
  47              container.Resolve<IHello> ().SayHello();
  48               container.Dispose();
  49           }
  50  
 51      }

配置文件

配置文件中 会在<typeAliases></typeAliases> 节点 为 需要注册的类增加别名。注意Type 是由 名空间.类名,程序集名 两部分构成的。

然后可以配置若干个Container,依据名字对其区分。

  1   <?  xml version="1.0"  ?> 
  2   <  configuration  > 
  3       <  configSections  > 
  4           <  section   name  ="unity"   type  ="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"  /> 
  5       </  configSections  > 
  6       <  unity  > 
  7           <  typeAliases  > 
  8               <  typeAlias   alias  ="SayHello"   type  ="ConAppUnityHelloWord.IHello,ConAppUnityHelloWord"  ></  typeAlias  > 
  9               <  typeAlias   alias  ="SayHelloA"   type  ="ConAppUnityHelloWord.ClassA,ConAppUnityHelloWord"  ></  typeAlias  > 
 10               <  typeAlias   alias  ="SayHelloB"   type  ="ConAppUnityHelloWord.ClassB,ConAppUnityHelloWord"  ></  typeAlias  > 
 11         <  typeAlias   alias  ="Log"   type  ="ConAppUnityHelloWord.ILog,ConAppUnityHelloWord"  ></  typeAlias  > 
 12         <  typeAlias   alias  ="PrintLog"   type  ="ConAppUnityHelloWord.PrintLog,ConAppUnityHelloWord"  ></  typeAlias  > 
 13           </  typeAliases  > 
 14           <  containers  > 
 15               <  container   name  ="Hello"  > 
 16                   <  types  > 
 17                       <  type   type  ="SayHello"   mapTo  ="SayHelloB"  > 
 18                           <!--  <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, 
  19                                        Microsoft.Practices.Unity.Configuration"></typeConfig>  --> 
 20                       </  type  > 
 21                   </  types  > 
 22               </  container  > 
 23         <  container   name  ="Log"  > 
 24           <  types  > 
 25             <  type   type  ="Log"   mapTo  ="PrintLog"  ></  type  > 
 26           </  types  > 
 27         </  container  > 
 28         <  container   name  ="SayHelloLog"  > 
 29           <  types  > 
 30             <  type   type  ="SayHello"   mapTo  ="SayHelloA"  ></  type  > 
 31             <  type   type  ="Log"   mapTo  ="PrintLog"  ></  type  > 
 32           </  types  > 
 33         </  container  > 
 34           </  containers  > 
 35       </  unity  > 
 36   <  startup  ><  supportedRuntime   version  ="v4.0"   sku  =".NETFramework,Version=v4.0"  /></  startup  ></  configuration  > 

类和接口

View Code

 1       interface   IHello
   2       {
   3  
  4           void   SayHello();
   5       }
   6  
  7       public   class   ClassB:IHello
   8       {
   9           public   void   SayHello()
  10           {
  11              Console.WriteLine( this  .GetType().Name);
  12           }
  13  
 14           public   ClassB()
  15           {
  16  
 17           }
  18  
 19           public   ClassB(ILog log)
  20           {
  21              log.Create( "  say hellob  "  );
  22           }
  23       }
  24  
 25  
 26       public   class   ClassA : IHello
  27       {
  28           public   void   SayHello()
  29           {
  30              Console.WriteLine( this  .GetType().Name);
  31           }
  32  
 33           public   ClassA()
  34           {
  35  
 36           }
  37  
 38           public   ClassA(ILog log)
  39           {
  40              log.Create( "  say helloa  "  );
  41           }
  42       }
  43  
 44       public   interface    ILog
  45       {
  46           void  Create( string   log);
  47       }
  48  
 49       public   class   PrintLog : ILog
  50       {
  51           public   void  Create( string   log)
  52           {
  53              Console.WriteLine( "  this is log    " + log);
  54           }
  55      }

对于 使用配置文件进行注入 理解上和使用编码方式差不多。都是将 组件映射到服务上,然后Container读取这些映射,Reslove出组件的实例。

不过这里还有一些疑问,等过些阵子明了了,再来解决。如果有路过的朋友能指点一二,将不胜感激。

1. Autofac中如果不注册 PrintLog  就无法ReslovePrintLog ,而Unity Application 中却可以,默认构造出该类的一个实例。这个差别是确实这样?还是代码有问题?。如果确实有这个差别,那么 二者存在这样差异在框架上又是什么原因。

2.如何通过Unity 的配置文件,注册 一个实例呢?就像RegisterInstance一样。疑惑中。

3. 还需要看一下Unity对 对象生命周期的管理。

初学IOC,理解浅薄,请各位朋友见谅指正。

该睡了,晚安。

 

 

分类:  Unity Application

标签:  IOC ,  Unity Application

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于Unity Application 学习的详细内容...

  阅读:42次