02-Unity深入浅出(二)
一. Unity聲明周期
? Unity容器為我們提供了6種生命周期,便于我們根據(jù)項目需求來選擇使用。
(1). 瞬時。默認省略即為瞬時,無論單線程還是多線程,每次都重新創(chuàng)建對象。new TransientLifetimeManager()
(2). 容器單例。只要是同一個Unity容器創(chuàng)建的同一個類型的對象,無論是線程之間還是單線程內(nèi)都是單例的。new ContainerControlledLifetimeManager()
(3). 線程單例。同一個線程內(nèi)創(chuàng)建的同一個類型的對象,都是單例的。但線程之間不是單例的。new PerThreadLifetimeManager()
(4). 分級容器單例。unity容器可以創(chuàng)建很多子容器,每個子容器無論怎么創(chuàng)建對象,都是單例的,但是子容器之間不是單例的。new HierarchicalLifetimeManager()
(5).?外部可釋放單例。在不銷毀的情況下,每次Resolve都會返回同一個對象,即是單例的;銷毀后,重新創(chuàng)建一個新的對象,銷毀后創(chuàng)建的新對象又是單例的。new ExternallyControlledLifetimeManager()
(6).循環(huán)引用。new PerResolveLifetimeManager(),不推薦使用,暫不測試。
下面同樣先通過代碼的形式來測試以上幾種情況。
?(1). 瞬時
1 { 2 Console.WriteLine("------------------- 05-Unity的生命周期-瞬時(1) -------------------"); 3 IUnityContainer container = new UnityContainer(); 4 container.RegisterType<IPhone, AndroidPhone>(new TransientLifetimeManager()); //默認省略就是瞬時的 5 6 //下面測試多線程中創(chuàng)建的對象是否是單例的(iphone1是一個線程 iphone2和iphone3是同一個線程) 7 IPhone iphone1 = null; 8 Action act1 = () => 9 { 10 iphone1 = container.Resolve<IPhone>(); 11 Console.WriteLine("iphone1由線程id={0}創(chuàng)建", 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}創(chuàng)建", Thread.CurrentThread.ManagedThreadId); 19 }; 20 //在act2的異步回調(diào)中創(chuàng)建iphone3(iphone2和iphone3是一個線程創(chuàng)建的) 21 IPhone iphone3 = null; 22 var result2 = act2.BeginInvoke(t => 23 { 24 iphone3 = container.Resolve<IPhone>(); 25 Console.WriteLine("iphone3由線程id={0}創(chuàng)建", Thread.CurrentThread.ManagedThreadId); 26 //代表兩個不同線程創(chuàng)建的對象 27 Console.WriteLine("iphone1和iphone2是否相等?{0}", object.ReferenceEquals(iphone1, iphone2)); 28 //代表同一個線程創(chuàng)建的兩個對象 29 Console.WriteLine("iphone2和iphone3是否相等?{0}", object.ReferenceEquals(iphone2, iphone3)); 30 }, null); 31 32 //線程等待 33 act1.EndInvoke(result1); 34 act2.EndInvoke(result2); 35 36 //總結(jié):瞬時創(chuàng)建無論單個線程內(nèi)還是多個線程之間,都不是單例的,每次調(diào)用都要重新創(chuàng)建對象 37 38 }分析:iphone2和iphone3是同一個線程創(chuàng)建的,iphone1是單獨一個線程創(chuàng)建的。經(jīng)過結(jié)果分析:iphone1和iphone2不相等,iphone2和iphone3不相等,證明:瞬時容器無論是線程內(nèi),還是線程與線程之間每次都是重新創(chuàng)建的,都不是單例。
?(2). 容器單例
1 { 2 Console.WriteLine("------------------- 05-Unity的生命周期-容器單例(2) -------------------"); 3 IUnityContainer container = new UnityContainer(); 4 container.RegisterType<IPhone, AndroidPhone>(new ContainerControlledLifetimeManager()); 5 6 //下面測試多線程中創(chuàng)建的對象是否是單例的(iphone1是一個線程 iphone2和iphone3是同一個線程) 7 IPhone iphone1 = null; 8 Action act1 = () => 9 { 10 iphone1 = container.Resolve<IPhone>(); 11 Console.WriteLine("iphone1由線程id={0}創(chuàng)建", 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}創(chuàng)建", Thread.CurrentThread.ManagedThreadId); 19 }; 20 //在act2的異步回調(diào)中創(chuàng)建iphone3(iphone2和iphone3是一個線程創(chuàng)建的) 21 IPhone iphone3 = null; 22 var result2 = act2.BeginInvoke(t => 23 { 24 iphone3 = container.Resolve<IPhone>(); 25 Console.WriteLine("iphone3由線程id={0}創(chuàng)建", Thread.CurrentThread.ManagedThreadId); 26 //代表兩個不同線程創(chuàng)建的對象 27 Console.WriteLine("iphone1和iphone2是否相等?{0}", object.ReferenceEquals(iphone1, iphone2)); 28 //代表同一個線程創(chuàng)建的兩個對象 29 Console.WriteLine("iphone2和iphone3是否相等?{0}", object.ReferenceEquals(iphone2, iphone3)); 30 }, null); 31 32 //線程等待 33 act1.EndInvoke(result1); 34 act2.EndInvoke(result2); 35 36 //總結(jié):容器單例:只要是同一個Unity容器創(chuàng)建的一個類,無論是線程之間還是單線程內(nèi)都是單例的 37 }分析:iphone2和iphone3是同一個線程創(chuàng)建的,iphone1是單獨一個線程創(chuàng)建的。經(jīng)過結(jié)果分析:iphone1和iphone2相等,iphone2和iphone3相等,證明:容器單例無論是線程內(nèi),還是線程與線程之間都是單例的。
?(3). 線程單例
1 { 2 Console.WriteLine("------------------- 05-Unity的生命周期-線程單例(3) -------------------"); 3 IUnityContainer container = new UnityContainer(); 4 container.RegisterType<IPhone, AndroidPhone>(new PerThreadLifetimeManager()); 5 6 //下面測試多線程中創(chuàng)建的對象是否是單例的(iphone1是一個線程 iphone2和iphone3是同一個線程) 7 IPhone iphone1 = null; 8 Action act1 = () => 9 { 10 iphone1 = container.Resolve<IPhone>(); 11 Console.WriteLine("iphone1由線程id={0}創(chuàng)建", 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}創(chuàng)建", Thread.CurrentThread.ManagedThreadId); 19 }; 20 //在act2的異步回調(diào)中創(chuàng)建iphone3(iphone2和iphone3是一個線程創(chuàng)建的) 21 IPhone iphone3 = null; 22 var result2 = act2.BeginInvoke(t => 23 { 24 iphone3 = container.Resolve<IPhone>(); 25 Console.WriteLine("iphone3由線程id={0}創(chuàng)建", Thread.CurrentThread.ManagedThreadId); 26 //代表兩個不同線程創(chuàng)建的對象 27 Console.WriteLine("iphone1和iphone2是否相等?{0}", object.ReferenceEquals(iphone1, iphone2)); 28 //代表同一個線程創(chuàng)建的兩個對象 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 * 總結(jié):線程單例:同一個線程內(nèi),eg:iphone2和iphone3,都是AndroidPhone類型,他是單例的,不重復(fù)創(chuàng)建,但是線程與線程之間創(chuàng)建的對象就不是單例的了。 38 * 與框架中EF上下文 利用CallContext保存的原理一致 39 一般來說不建議在使用RegisterInstance對已存在的對象注冊關(guān)系時使用PerThreadLifetimeManager,因為此時的對象已經(jīng)在一個線程內(nèi)創(chuàng)建了,如果再使用這個生命周期管理器,將無法保證其正確調(diào)用 40 */ 41 }分析:iphone2和iphone3是同一個線程創(chuàng)建的,iphone1是單獨一個線程創(chuàng)建的。經(jīng)過結(jié)果分析:iphone1和iphone2不相等,iphone2和iphone3相等,證明:線程單例在線程內(nèi)是單例的,但線程與線程之間不是單例的。
?(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第一次創(chuàng)建的對象的hashCode值:{0}", iphone1.GetHashCode()); 21 Console.WriteLine("父容器container第二次創(chuàng)建的對象的hashCode值:{0}", iphone2.GetHashCode()); 22 23 Console.WriteLine("子容器childContainer1第一次創(chuàng)建的對象的hashCode值:{0}", iphone3.GetHashCode()); 24 Console.WriteLine("子容器childContainer1第二次創(chuàng)建的對象的hashCode值:{0}", iphone4.GetHashCode()); 25 26 Console.WriteLine("子容器childContainer2第一次創(chuàng)建的對象的hashCode值:{0}", iphone5.GetHashCode()); 27 Console.WriteLine("子容器childContainer2第二次創(chuàng)建的對象的hashCode值:{0}", iphone6.GetHashCode()); 28 29 //總結(jié):unity容器可以創(chuàng)建很多子容器,每個子容器無論怎么創(chuàng)建對象,都是單例的,但是子容器之間不是單例的。 30 //好處:我們可以對于不同生命周期的對象放在不同容器中,如果一個子容器釋放,不會影響其它子容器的對象, 31 //但是如果根節(jié)點處的父容器被釋放,所有的子容器都將被釋放 32 }分析:每個子容器創(chuàng)建的對象的值是相同的,子容器之間創(chuàng)建的對象是不同的
?(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("第一次調(diào)用:{0}", iphone1.GetHashCode()); 9 Console.WriteLine("第二次調(diào)用:{0}", iphone2.GetHashCode()); 10 11 Console.WriteLine("------------------ GC回收過后 ------------------------"); 12 iphone1 = iphone2 = null; 13 GC.Collect(); 14 Console.WriteLine("回收后第一次調(diào)用:{0}", container.Resolve<IPhone>().GetHashCode()); 15 Console.WriteLine("回收后第二次調(diào)用:{0}", container.Resolve<IPhone>().GetHashCode()); 16 17 //總結(jié):在不銷毀的情況下,每次Resolve都會返回同一個對象,即是單例的;銷毀后,重新創(chuàng)建一個新的對象 18 //銷毀后創(chuàng)建的新對象又是單例的。 19 20 21 }分析:回收前創(chuàng)建的對象都是單例的,回收后重新創(chuàng)建的對象還是單例的。
?(6). 循環(huán)引用
? 不推薦使用。
?
二. 配置文件的形式實現(xiàn)
Unity在實際開發(fā)環(huán)境中,?注冊類型(包括注入對象、聲明生命周期)的那一步,都是在配置文件中聲明的,這才是Unity的真諦所在,才能實現(xiàn)真正意義上的解耦,只需將Service層的DLL文件復(fù)制到主程序bin文件夾中即可,不需要直接添加對Service層的引用。
該實現(xiàn)形式主要分為以下幾步:
(1). 編寫配置文件的內(nèi)容。(需要將該配置文件的屬性改為“始終復(fù)制”,使其可以生成到主程序的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容器,并與配置文件關(guān)聯(lián)。
1 IUnityContainer container = new UnityContainer(); 2 section.Configure(container, "testContainer"); View Code(4). Unity解析對象。
?(一).配置文件的書寫形式
下面整個Xml均為Untiy的配置文件,聲明Unity容器有兩種方式:①先定義別名,類型名稱和程序集名稱均寫在別名中,然后在容器中與別名進行關(guān)聯(lián)。 ②直接在容器中的register節(jié)點寫類型名稱和程序集名稱。
? 另外可以在register節(jié)點中添加<lifetime>節(jié)點,可以聲明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的兩個參數(shù)分別是:類型名稱和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容器配置注冊節(jié)點--> 27 <containers> 28 <!--容器配置方式一:類型名稱和程序集名稱全部寫在容器中--> 29 <container name="testContainer"> 30 <!-- type和mapTo中的兩個參數(shù)分別是:類型名稱和DLL程序集的名稱 --> 31 <!-- type和mapTo分別對應(yīng)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 <!--以下三個屬于依賴注入的內(nèi)容了--> 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中的兩個參數(shù)分別是:類型名稱和DLL程序集的名稱 --> 44 <!-- type和mapTo分別對應(yīng)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 <!--以下三個屬于依賴注入的內(nèi)容了--> 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分別對應(yīng)上面的別名 --> 57 <!-- 聲明周期放到該節(jié)點里面用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. 編寫配置文件中的內(nèi)容(需要將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. 編寫配置文件中的內(nèi)容(需要將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的生命周期-容器單例--配置文件的方式 (可以注釋配置文件中的節(jié)點,來測試其他情況:瞬時、線程單例)
?
1 Console.WriteLine("------------------- Unity的生命周期-容器單例--配置文件的方式 -------------------"); 2 //1. 編寫配置文件中的內(nèi)容(需要將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 //下面測試多線程中創(chuàng)建的對象是否是單例的(iphone1是一個線程 iphone2和iphone3是同一個線程) 13 IPhone iphone1 = null; 14 Action act1 = () => 15 { 16 iphone1 = container.Resolve<IPhone>(); 17 Console.WriteLine("iphone1由線程id={0}創(chuàng)建", 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}創(chuàng)建", Thread.CurrentThread.ManagedThreadId); 25 }; 26 //在act2的異步回調(diào)中創(chuàng)建iphone3(iphone2和iphone3是一個線程創(chuàng)建的) 27 IPhone iphone3 = null; 28 var result2 = act2.BeginInvoke(t => 29 { 30 iphone3 = container.Resolve<IPhone>(); 31 Console.WriteLine("iphone3由線程id={0}創(chuàng)建", Thread.CurrentThread.ManagedThreadId); 32 //代表兩個不同線程創(chuàng)建的對象 33 Console.WriteLine("iphone1和iphone2是否相等?{0}", object.ReferenceEquals(iphone1, iphone2)); 34 //代表同一個線程創(chuàng)建的兩個對象 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. 編寫配置文件中的內(nèi)容(需要將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第一次創(chuàng)建的對象的hashCode值:{0}", iphone1.GetHashCode()); 26 Console.WriteLine("父容器container第二次創(chuàng)建的對象的hashCode值:{0}", iphone2.GetHashCode()); 27 28 Console.WriteLine("子容器childContainer1第一次創(chuàng)建的對象的hashCode值:{0}", iphone3.GetHashCode()); 29 Console.WriteLine("子容器childContainer1第二次創(chuàng)建的對象的hashCode值:{0}", iphone4.GetHashCode()); 30 31 Console.WriteLine("子容器childContainer2第一次創(chuàng)建的對象的hashCode值:{0}", iphone5.GetHashCode()); 32 Console.WriteLine("子容器childContainer2第二次創(chuàng)建的對象的hashCode值:{0}", iphone6.GetHashCode());?
三. Unity實現(xiàn)AOP
?待定
?
轉(zhuǎn)載于:https://www.cnblogs.com/yaopengfei/p/7500113.html
《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的02-Unity深入浅出(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ZooKeeper:win7上安装单机及
- 下一篇: 访问兄弟节点