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

     待定

  • 相关阅读:
    DevOps、CI、CD都是什么鬼?
    卧槽!华为《Linux中文手册》火了,完整版 PDF 开放下载!
    MongoDB 常用运维实践总结
    谈谈变更过程中的运维意识
    Ping原理详解
    为什么Redis要比Memcached更火?
    一篇文章教你搞懂日志采集利器 Filebeat
    工程师姓什么很重要!别再叫我“X工”!!!
    这些 Shell 分析服务器日志命令集锦,收藏好
    Linux下找出吃内存的方法总结
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/7500113.html
Copyright © 2011-2022 走看看