zoukankan      html  css  js  c++  java
  • 02-Unity深入浅出(二)

    一. Unity声明周期

       Unity容器为我们提供了6种生命周期,便于我们根据项目需求来选择使用。

      (1). 瞬时。默认省略即为瞬时,无论单线程还是多线程,每次都重新创建对象。new TransientLifetimeManager()

      (2). 容器单例。只要是同一个Unity容器创建的同一个类型的对象,无论是线程之间还是单线程内都是单例的。new ContainerControlledLifetimeManager()

      (3). 线程单例。同一个线程内创建的同一个类型的对象,都是单例的。但线程之间不是单例的。new PerThreadLifetimeManager()

      (4). 分级容器单例。unity容器可以创建很多子容器,每个子容器无论怎么创建对象,都是单例的,但是子容器之间不是单例的。new HierarchicalLifetimeManager()

      (5). 外部可释放单例。在不销毁的情况下,每次Resolve都会返回同一个对象,即是单例的;销毁后,重新创建一个新的对象,销毁后创建的新对象又是单例的。new ExternallyControlledLifetimeManager()

      (6).循环引用。new PerResolveLifetimeManager(),不推荐使用,暂不测试。

      下面同样先通过代码的形式来测试以上几种情况。

     (1). 瞬时

     1  {
     2                 Console.WriteLine("-------------------  05-Unity的生命周期-瞬时(1)  -------------------");
     3                 IUnityContainer container = new UnityContainer();
     4                 container.RegisterType<IPhone, AndroidPhone>(new TransientLifetimeManager());   //默认省略就是瞬时的
     5 
     6                 //下面测试多线程中创建的对象是否是单例的(iphone1是一个线程  iphone2和iphone3是同一个线程)
     7                 IPhone iphone1 = null;
     8                 Action act1 = () =>
     9                 {
    10                     iphone1 = container.Resolve<IPhone>();
    11                     Console.WriteLine("iphone1由线程id={0}创建", Thread.CurrentThread.ManagedThreadId);
    12                 };
    13                 var result1 = act1.BeginInvoke(null, null);
    14                 IPhone iphone2 = null;
    15                 Action act2 = () =>
    16                 {
    17                     iphone2 = container.Resolve<IPhone>();
    18                     Console.WriteLine("iphone2由线程id={0}创建", Thread.CurrentThread.ManagedThreadId);
    19                 };
    20                 //在act2的异步回调中创建iphone3(iphone2和iphone3是一个线程创建的)
    21                 IPhone iphone3 = null;
    22                 var result2 = act2.BeginInvoke(t =>
    23                 {
    24                     iphone3 = container.Resolve<IPhone>();
    25                     Console.WriteLine("iphone3由线程id={0}创建", Thread.CurrentThread.ManagedThreadId);
    26                     //代表两个不同线程创建的对象
    27                     Console.WriteLine("iphone1和iphone2是否相等?{0}", object.ReferenceEquals(iphone1, iphone2));
    28                     //代表同一个线程创建的两个对象
    29                     Console.WriteLine("iphone2和iphone3是否相等?{0}", object.ReferenceEquals(iphone2, iphone3));
    30                 }, null);
    31 
    32                 //线程等待
    33                 act1.EndInvoke(result1);
    34                 act2.EndInvoke(result2);
    35 
    36                 //总结:瞬时创建无论单个线程内还是多个线程之间,都不是单例的,每次调用都要重新创建对象
    37 
    38             }

      分析:iphone2和iphone3是同一个线程创建的,iphone1是单独一个线程创建的。经过结果分析:iphone1和iphone2不相等,iphone2和iphone3不相等,证明:瞬时容器无论是线程内,还是线程与线程之间每次都是重新创建的,都不是单例。

     (2). 容器单例

     1   {
     2                 Console.WriteLine("-------------------  05-Unity的生命周期-容器单例(2)  -------------------");
     3                 IUnityContainer container = new UnityContainer();
     4                 container.RegisterType<IPhone, AndroidPhone>(new ContainerControlledLifetimeManager());
     5 
     6                 //下面测试多线程中创建的对象是否是单例的(iphone1是一个线程  iphone2和iphone3是同一个线程)
     7                 IPhone iphone1 = null;
     8                 Action act1 = () =>
     9                 {
    10                     iphone1 = container.Resolve<IPhone>();
    11                     Console.WriteLine("iphone1由线程id={0}创建", Thread.CurrentThread.ManagedThreadId);
    12                 };
    13                 var result1 = act1.BeginInvoke(null, null);
    14                 IPhone iphone2 = null;
    15                 Action act2 = () =>
    16                 {
    17                     iphone2 = container.Resolve<IPhone>();
    18                     Console.WriteLine("iphone2由线程id={0}创建", Thread.CurrentThread.ManagedThreadId);
    19                 };
    20                 //在act2的异步回调中创建iphone3(iphone2和iphone3是一个线程创建的)
    21                 IPhone iphone3 = null;
    22                 var result2 = act2.BeginInvoke(t =>
    23                 {
    24                     iphone3 = container.Resolve<IPhone>();
    25                     Console.WriteLine("iphone3由线程id={0}创建", Thread.CurrentThread.ManagedThreadId);
    26                     //代表两个不同线程创建的对象
    27                     Console.WriteLine("iphone1和iphone2是否相等?{0}", object.ReferenceEquals(iphone1, iphone2));
    28                     //代表同一个线程创建的两个对象
    29                     Console.WriteLine("iphone2和iphone3是否相等?{0}", object.ReferenceEquals(iphone2, iphone3));
    30                 }, null);
    31 
    32                 //线程等待
    33                 act1.EndInvoke(result1);
    34                 act2.EndInvoke(result2);
    35 
    36                 //总结:容器单例:只要是同一个Unity容器创建的一个类,无论是线程之间还是单线程内都是单例的
    37             }

      分析:iphone2和iphone3是同一个线程创建的,iphone1是单独一个线程创建的。经过结果分析:iphone1和iphone2相等,iphone2和iphone3相等,证明:容器单例无论是线程内,还是线程与线程之间都是单例的。

     (3). 线程单例

     1  {
     2                 Console.WriteLine("-------------------  05-Unity的生命周期-线程单例(3)  -------------------");
     3                 IUnityContainer container = new UnityContainer();
     4                 container.RegisterType<IPhone, AndroidPhone>(new PerThreadLifetimeManager());
     5 
     6                 //下面测试多线程中创建的对象是否是单例的(iphone1是一个线程  iphone2和iphone3是同一个线程)
     7                 IPhone iphone1 = null;
     8                 Action act1 = () =>
     9                 {
    10                     iphone1 = container.Resolve<IPhone>();
    11                     Console.WriteLine("iphone1由线程id={0}创建", Thread.CurrentThread.ManagedThreadId);
    12                 };
    13                 var result1 = act1.BeginInvoke(null, null);
    14                 IPhone iphone2 = null;
    15                 Action act2 = () =>
    16                 {
    17                     iphone2 = container.Resolve<IPhone>();
    18                     Console.WriteLine("iphone2由线程id={0}创建", Thread.CurrentThread.ManagedThreadId);
    19                 };
    20                 //在act2的异步回调中创建iphone3(iphone2和iphone3是一个线程创建的)
    21                 IPhone iphone3 = null;
    22                 var result2 = act2.BeginInvoke(t =>
    23                 {
    24                     iphone3 = container.Resolve<IPhone>();
    25                     Console.WriteLine("iphone3由线程id={0}创建", Thread.CurrentThread.ManagedThreadId);
    26                         //代表两个不同线程创建的对象
    27                         Console.WriteLine("iphone1和iphone2是否相等?{0}", object.ReferenceEquals(iphone1, iphone2));
    28                         //代表同一个线程创建的两个对象
    29                         Console.WriteLine("iphone2和iphone3是否相等?{0}", object.ReferenceEquals(iphone2, iphone3));
    30                 }, null);
    31 
    32                 //线程等待
    33                 act1.EndInvoke(result1);
    34                 act2.EndInvoke(result2);
    35 
    36                 /*
    37                  * 总结:线程单例:同一个线程内,eg:iphone2和iphone3,都是AndroidPhone类型,他是单例的,不重复创建,但是线程与线程之间创建的对象就不是单例的了。
    38                  * 与框架中EF上下文 利用CallContext保存的原理一致
    39                  一般来说不建议在使用RegisterInstance对已存在的对象注册关系时使用PerThreadLifetimeManager,因为此时的对象已经在一个线程内创建了,如果再使用这个生命周期管理器,将无法保证其正确调用
    40                  */
    41             }

      分析:iphone2和iphone3是同一个线程创建的,iphone1是单独一个线程创建的。经过结果分析:iphone1和iphone2不相等,iphone2和iphone3相等,证明:线程单例在线程内是单例的,但线程与线程之间不是单例的。

     (4). 分级容器单例

     1  {
     2                 Console.WriteLine("-------------------  05-Unity的生命周期-分级容器单例(4)  -------------------");
     3                 //父Unity容器
     4                 IUnityContainer container = new UnityContainer();
     5                 container.RegisterType<IPhone, AndroidPhone>(new HierarchicalLifetimeManager());
     6                 //子Unity容器1
     7                 IUnityContainer childContainer1 = container.CreateChildContainer();
     8                 childContainer1.RegisterType<IPhone, AndroidPhone>(new HierarchicalLifetimeManager());
     9                 //子Unity容器2
    10                 IUnityContainer childContainer2 = container.CreateChildContainer();
    11                 childContainer2.RegisterType<IPhone, AndroidPhone>(new HierarchicalLifetimeManager());
    12 
    13                 IPhone iphone1 = container.Resolve<IPhone>();
    14                 IPhone iphone2 = container.Resolve<IPhone>();
    15                 IPhone iphone3 = childContainer1.Resolve<IPhone>();
    16                 IPhone iphone4 = childContainer1.Resolve<IPhone>();
    17                 IPhone iphone5 = childContainer2.Resolve<IPhone>();
    18                 IPhone iphone6 = childContainer2.Resolve<IPhone>();
    19 
    20                 Console.WriteLine("父容器container第一次创建的对象的hashCode值:{0}", iphone1.GetHashCode());
    21                 Console.WriteLine("父容器container第二次创建的对象的hashCode值:{0}", iphone2.GetHashCode());
    22 
    23                 Console.WriteLine("子容器childContainer1第一次创建的对象的hashCode值:{0}", iphone3.GetHashCode());
    24                 Console.WriteLine("子容器childContainer1第二次创建的对象的hashCode值:{0}", iphone4.GetHashCode());
    25 
    26                 Console.WriteLine("子容器childContainer2第一次创建的对象的hashCode值:{0}", iphone5.GetHashCode());
    27                 Console.WriteLine("子容器childContainer2第二次创建的对象的hashCode值:{0}", iphone6.GetHashCode());
    28 
    29                 //总结:unity容器可以创建很多子容器,每个子容器无论怎么创建对象,都是单例的,但是子容器之间不是单例的。
    30                 //好处:我们可以对于不同生命周期的对象放在不同容器中,如果一个子容器释放,不会影响其它子容器的对象,
    31                 //但是如果根节点处的父容器被释放,所有的子容器都将被释放
    32             }

      分析:每个子容器创建的对象的值是相同的,子容器之间创建的对象是不同的

     (5). 外部可释放单例

     1   {
     2                 Console.WriteLine("------------------- 05-Unity的生命周期-外部可释放单例(5)  -------------------");
     3                 IUnityContainer container = new UnityContainer();
     4                 container.RegisterType<IPhone, AndroidPhone>(new ExternallyControlledLifetimeManager());
     5 
     6                 IPhone iphone1 = container.Resolve<IPhone>();
     7                 IPhone iphone2 = container.Resolve<IPhone>();
     8                 Console.WriteLine("第一次调用:{0}", iphone1.GetHashCode());
     9                 Console.WriteLine("第二次调用:{0}", iphone2.GetHashCode());
    10 
    11                 Console.WriteLine("------------------ GC回收过后  ------------------------");
    12                 iphone1 = iphone2 = null;
    13                 GC.Collect();
    14                 Console.WriteLine("回收后第一次调用:{0}", container.Resolve<IPhone>().GetHashCode());
    15                 Console.WriteLine("回收后第二次调用:{0}", container.Resolve<IPhone>().GetHashCode());
    16 
    17                 //总结:在不销毁的情况下,每次Resolve都会返回同一个对象,即是单例的;销毁后,重新创建一个新的对象
    18                 //销毁后创建的新对象又是单例的。
    19 
    20 
    21             }

      分析:回收前创建的对象都是单例的,回收后重新创建的对象还是单例的。

     (6). 循环引用

       不推荐使用。

    二. 配置文件的形式实现

      Unity在实际开发环境中, 注册类型(包括注入对象、声明生命周期)的那一步,都是在配置文件中声明的,这才是Unity的真谛所在,才能实现真正意义上的解耦,只需将Service层的DLL文件复制到主程序bin文件夹中即可,不需要直接添加对Service层的引用。

      该实现形式主要分为以下几步:

      (1). 编写配置文件的内容。(需要将该配置文件的属性改为“始终复制”,使其可以生成到主程序的bin文件中)。

          (2). 固定4行代码读取配置文件。

    1   ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
    2                     fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\UnityConfig.xml");//找配置文件的路径
    3                     Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
    4                     UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
    View Code

      (3). 声明Unity容器,并与配置文件关联。

    1    IUnityContainer container = new UnityContainer();
    2    section.Configure(container, "testContainer");
    View Code

      (4). Unity解析对象。

     (一).配置文件的书写形式

      下面整个Xml均为Untiy的配置文件,声明Unity容器有两种方式:①先定义别名,类型名称和程序集名称均写在别名中,然后在容器中与别名进行关联。 ②直接在容器中的register节点写类型名称和程序集名称。

       另外可以在register节点中添加<lifetime>节点,可以声明Unity的声明周期。

     1 <configuration>
     2   <configSections>
     3     <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
     4   </configSections>
     5   <unity>
     6     <!-- unity容器支持AOP扩展  -->
     7     <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration"/>
     8    
     9     <!--定义类型别名-->
    10     <aliases>
    11       <!--type的两个参数分别是:类型名称和DLL程序集的名称-->
    12       <!--alias中的别名供container容器中使用-->
    13       <add alias="IPhone" type="Ypf.Interface.IPhone,Ypf.Interface" />
    14       <add alias="AndroidPhone" type="Ypf.Service.AndroidPhone, Ypf.Service" />
    15       <add alias="ApplePhone" type="Ypf.Service.ApplePhone, Ypf.Service" />
    16       
    17       <add alias="IMicrophone" type="Ypf.Interface.IMicrophone, Ypf.Interface" />
    18       <add alias="IHeadphone" type="Ypf.Interface.IHeadphone, Ypf.Interface" />
    19       <add alias="IPower" type="Ypf.Interface.IPower, Ypf.Interface" />
    20       <add alias="Microphone" type="Ypf.Service.Microphone, Ypf.Service" />
    21       <add alias="Headphone" type="Ypf.Service.Headphone, Ypf.Service" />
    22       <add alias="Power" type="Ypf.Service.Power, Ypf.Service" />
    23     </aliases>
    24     
    25     
    26     <!-- unity容器配置注册节点-->
    27     <containers>   
    28       <!--容器配置方式一:类型名称和程序集名称全部写在容器中-->
    29       <container name="testContainer">
    30         <!--  type和mapTo中的两个参数分别是:类型名称和DLL程序集的名称 -->
    31         <!--  type和mapTo分别对应RegisterType<A,B> 中的A和B两个值-->
    32         <register type="Ypf.Interface.IPhone,Ypf.Interface" mapTo="Ypf.Service.AndroidPhone, Ypf.Service"/>
    33         <register type="Ypf.Interface.IPhone,Ypf.Interface" mapTo="Ypf.Service.AndroidPhone, Ypf.Service" name="android"/>
    34         <register type="Ypf.Interface.IPhone,Ypf.Interface" mapTo="Ypf.Service.ApplePhone, Ypf.Service" name="apple"/>
    35         <!--以下三个属于依赖注入的内容了-->
    36         <register type="Ypf.Interface.IMicrophone, Ypf.Interface" mapTo="Ypf.Service.Microphone, Ypf.Service"/>
    37         <register type="Ypf.Interface.IHeadphone, Ypf.Interface" mapTo="Ypf.Service.Headphone, Ypf.Service"/>
    38         <register type="Ypf.Interface.IPower, Ypf.Interface" mapTo="Ypf.Service.Power, Ypf.Service"/>
    39       </container>
    40 
    41       <!--容器配置方式二:配合aliases类型别名进行使用-->
    42       <container name="testContainer2">
    43         <!--  type和mapTo中的两个参数分别是:类型名称和DLL程序集的名称 -->
    44         <!--  type和mapTo分别对应RegisterType<A,B> 中的A和B两个值-->
    45         <register type="IPhone" mapTo="AndroidPhone"/>
    46         <register type="IPhone" mapTo="AndroidPhone" name="android"/>
    47         <register type="IPhone" mapTo="ApplePhone" name="apple"/>
    48         <!--以下三个属于依赖注入的内容了-->
    49         <register type="IMicrophone" mapTo="Microphone"/>
    50         <register type="IHeadphone" mapTo="Headphone"/>
    51         <register type="IPower" mapTo="Power"/>
    52       </container>
    53 
    54       <!--在配置文件中配置Unity的生命周期 以AndroidPhone为例-->
    55       <container name="testContainer3">
    56         <!--  下面是用别名的形式, type和mapto分别对应上面的别名 -->
    57         <!--  声明周期放到该节点里面用lifetime进行包裹,不用别名的形式道理一样,也是这种方式进行包裹-->
    58         <register type="IPhone" mapTo="AndroidPhone">
    59           <!--1. 瞬时的  默认即为瞬时的-->
    60           <!--<lifetime type="TransientLifetimeManager" />-->    
    61           <!--2. 容器单例的-->
    62           <!--<lifetime type="ContainerControlledLifetimeManager" />-->
    63           <!--3. 线程单例-->
    64           <!--<lifetime type="PerThreadLifetimeManager" />-->
    65           <!--4. 分级容器单例-->
    66           <lifetime type="hierarchical" />
    67           <!--其它两种不做测试-->
    68         </register>
    69       </container>
    70     </containers>
    71     
    72   </unity>
    73 </configuration>

     (二). 容器配置方式一:类型名称和程序集名称全部写在容器中

     {
                        //Console.WriteLine("---------------------------容器配置方式一:类型名称和程序集名称全部写在容器中--------------------------------------");
                        ///*(一). 该配置文件包含依赖注入、指定命名注册*/
    
                        ////1. 编写配置文件中的内容(需要将UnityConfig.xml的属性改为始终赋值,使其能生成到bin下)
                        ////2. 固定的4行代码读取配置文件
                        ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
                        fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\UnityConfig.xml");//找配置文件的路径
                        Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
                        UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
                        ////3. Unity层次的步骤
                        IUnityContainer container = new UnityContainer();
                        section.Configure(container, "testContainer");
    
                        IPhone iphone1 = container.Resolve<IPhone>();
                        iphone1.Call();
                        IPhone iphone2 = container.Resolve<IPhone>("apple");
                        iphone2.Call();
                        IPhone iphone3 = container.Resolve<IPhone>("android");
                        iphone3.Call();
    
                    }

     (三). 容器配置方式二:配合aliases类型别名进行使用

     1  {
     2                     //Console.WriteLine("---------------------------容器配置方式二:配合aliases类型别名进行使用--------------------------------------");
     3                     ///*(一). 该配置文件包含依赖注入、指定命名注册*/
     4 
     5                     //1. 编写配置文件中的内容(需要将UnityConfig.xml的属性改为始终赋值,使其能生成到bin下)
     6                     //2. 固定的4行代码读取配置文件
     7                     ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
     8                     fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\UnityConfig.xml");//找配置文件的路径
     9                     Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
    10                     UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
    11                     //3. Unity层次的步骤
    12                     IUnityContainer container = new UnityContainer();
    13                     section.Configure(container, "testContainer2");
    14 
    15                     IPhone iphone1 = container.Resolve<IPhone>();
    16                     iphone1.Call();
    17                     IPhone iphone2 = container.Resolve<IPhone>("apple");
    18                     iphone2.Call();
    19                     IPhone iphone3 = container.Resolve<IPhone>("android");
    20                     iphone3.Call();
    21                 }

     (四). Unity的生命周期-容器单例--配置文件的方式 (可以注释配置文件中的节点,来测试其他情况:瞬时、线程单例)

     1                     Console.WriteLine("-------------------  Unity的生命周期-容器单例--配置文件的方式  -------------------");
     2                     //1. 编写配置文件中的内容(需要将UnityConfig.xml的属性改为始终赋值,使其能生成到bin下)
     3                     //2. 固定的4行代码读取配置文件
     4                     ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
     5                     fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\UnityConfig.xml");//找配置文件的路径
     6                     Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
     7                     UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
     8                     //3. Unity层次的步骤
     9                     IUnityContainer container = new UnityContainer();
    10                     section.Configure(container, "testContainer3");
    11 
    12                     //下面测试多线程中创建的对象是否是单例的(iphone1是一个线程  iphone2和iphone3是同一个线程)
    13                     IPhone iphone1 = null;
    14                     Action act1 = () =>
    15                     {
    16                         iphone1 = container.Resolve<IPhone>();
    17                         Console.WriteLine("iphone1由线程id={0}创建", Thread.CurrentThread.ManagedThreadId);
    18                     };
    19                     var result1 = act1.BeginInvoke(null, null);
    20                     IPhone iphone2 = null;
    21                     Action act2 = () =>
    22                     {
    23                         iphone2 = container.Resolve<IPhone>();
    24                         Console.WriteLine("iphone2由线程id={0}创建", Thread.CurrentThread.ManagedThreadId);
    25                     };
    26                     //在act2的异步回调中创建iphone3(iphone2和iphone3是一个线程创建的)
    27                     IPhone iphone3 = null;
    28                     var result2 = act2.BeginInvoke(t =>
    29                     {
    30                         iphone3 = container.Resolve<IPhone>();
    31                         Console.WriteLine("iphone3由线程id={0}创建", Thread.CurrentThread.ManagedThreadId);
    32                         //代表两个不同线程创建的对象
    33                         Console.WriteLine("iphone1和iphone2是否相等?{0}", object.ReferenceEquals(iphone1, iphone2));
    34                         //代表同一个线程创建的两个对象
    35                         Console.WriteLine("iphone2和iphone3是否相等?{0}", object.ReferenceEquals(iphone2, iphone3));
    36                     }, null);
    37 
    38                     //线程等待
    39                     act1.EndInvoke(result1);
    40                     act2.EndInvoke(result2);

     (五). Unity的生命周期-分级容器-配置文件

     1                     Console.WriteLine("-------------------  Unity的生命周期-分级容器--配置文件的方式  -------------------");
     2                     //1. 编写配置文件中的内容(需要将UnityConfig.xml的属性改为始终赋值,使其能生成到bin下)
     3                     //2. 固定的4行代码读取配置文件
     4                     ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
     5                     fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\UnityConfig.xml");//找配置文件的路径
     6                     Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
     7                     UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
     8                     //3. Unity层次的步骤
     9                     IUnityContainer container = new UnityContainer();
    10                     section.Configure(container, "testContainer3");
    11 
    12                     //子Unity容器1
    13                     IUnityContainer childContainer1 = container.CreateChildContainer();
    14 
    15                     //子Unity容器2
    16                     IUnityContainer childContainer2 = container.CreateChildContainer();
    17 
    18                     IPhone iphone1 = container.Resolve<IPhone>();
    19                     IPhone iphone2 = container.Resolve<IPhone>();
    20                     IPhone iphone3 = childContainer1.Resolve<IPhone>();
    21                     IPhone iphone4 = childContainer1.Resolve<IPhone>();
    22                     IPhone iphone5 = childContainer2.Resolve<IPhone>();
    23                     IPhone iphone6 = childContainer2.Resolve<IPhone>();
    24 
    25                     Console.WriteLine("父容器container第一次创建的对象的hashCode值:{0}", iphone1.GetHashCode());
    26                     Console.WriteLine("父容器container第二次创建的对象的hashCode值:{0}", iphone2.GetHashCode());
    27 
    28                     Console.WriteLine("子容器childContainer1第一次创建的对象的hashCode值:{0}", iphone3.GetHashCode());
    29                     Console.WriteLine("子容器childContainer1第二次创建的对象的hashCode值:{0}", iphone4.GetHashCode());
    30 
    31                     Console.WriteLine("子容器childContainer2第一次创建的对象的hashCode值:{0}", iphone5.GetHashCode());
    32                     Console.WriteLine("子容器childContainer2第二次创建的对象的hashCode值:{0}", iphone6.GetHashCode());

    三. Unity实现AOP

     待定

  • 相关阅读:
    【转+补充】在OpenCV for Android 2.4.5中使用SURF(nonfree module)
    Delphi StarOffice Framework Beta 1.0 发布
    Angular ngIf相关问题
    angularjs文档下载
    公众号微信支付开发
    公众号第三方平台开发 教程六 代公众号使用JS SDK说明
    公众号第三方平台开发 教程五 代公众号处理消息和事件
    公众号第三方平台开发 教程四 代公众号发起网页授权说明
    公众号第三方平台开发 教程三 微信公众号授权第三方平台
    公众号第三方平台开发 教程二 component_verify_ticket和accessToken的获取
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/7500113.html
Copyright © 2011-2022 走看看