zoukankan      html  css  js  c++  java
  • 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,理解浅薄,请各位朋友见谅指正。

    该睡了,晚安。

     
     
  • 相关阅读:
    06 Python类、对象
    05 Python DNS域名轮询业务监控
    04 Python字符串
    03 Python函数
    02 Python循环
    执行config文件时,config.log中报错xcrun: error: active developer path ("/Applications/Xcode.app/Contents/Developer") does not exist, use xcode-select to change
    浏览我的php网页时,出现的都是网页的代码
    php
    [转载]用c写PHP的扩展接口(php5,c++)
    PHP扩展编写示例
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2974766.html
Copyright © 2011-2022 走看看