程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Unity 1.2使用初探(2)

Unity 1.2使用初探(2)

編輯:關於.NET

繼續我們的Unity 1.2使用初探,在上節"Unity 1.2使用初探(1)"中,我們 主要編碼的形式展示了Unity的編碼方式實現。下面我們講討論使用配置文件實現 。

這裡我們繼續使用上節的代碼:

namespace DailyPractice.UnityEx
{
public interface ILogService
{
void Write(string message);
}
 
public class CnsLogService: ILogService
{
#region ILogService 成員
 
public void Write(string message) {
Console.WriteLine(String.Format("Cns-exception msg:{0}", message));
}
#endregion
}
 
public class DataLogService:ILogService
{
#region ILogService 成員
 
public void Write(string message) {
DailyPractice.Utility.Log.AddLog(message);
}
#endregion
}
}
 
namespace DailyPractice.Utility
{
public class Log
{
public static void AddLog(string message) {
//insert into Log(message) values(@message)
Console.WriteLine(String.Format("Data-exception msg:{0}", message));
}
}
}

這段代碼主要實現了ILogService接口,然後我們以配置文件去實現,編寫如 下的配置文件:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity" 

type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection

, Microsoft.Practices.Unity.Configuration" />
</configSections>
 
<unity>
<containers>
<container name="One">
<types>
<type type="DailyPractice.UnityEx.ILogService, 

DailyPractice.UnityEx"
mapTo="DailyPractice.UnityEx.DataLogService, 

DailyPractice.UnityEx"/>
</types>
</container>
</containers>
</unity>
</configuration>

這裡我進行相關的說明,configSections配置節的是unity固定配置,通過配 置文件實現Unity,先要進行此配置:

<section name="unity" 

type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection

, Microsoft.Practices.Unity.Configuration" />

然後,我們在看<unity>裡面的配置:

<containers>是必須元素,其內可有多container個元素,container元 素就是每一個容器的配置,它有一個可選的 name屬性,用於指定容器的名稱。

container元素有下列子元素: types元素 ,instances元素, extensions元 素。

這裡主要說type元素,在文檔中有這麼一句:

The type element defines a type mapping for the Unity container. If you specify a name, that name is used for the type mapping. If you do not specify a name, it creates a default mapping for the specified types. You can specify a lifetime manager for each mapping. If no explicit lifetime manager is configured for a type, transient lifetime management is exercised.

大致的意思就是或type元素定義了一個指向的type,如果你指定了一個name, 那麼就以你指定的來mapping,否則則創建一個一個默認的mapping for the specified types,你還可以指定lifetime manager,如果你不指定,將應用 transient lifetime management。

mapTo是: The actual Type object for the mapTo element in the configuration file.

所以根據以上,可以知道我們是在以 DataLogService 進行 container映射。

然後就是代碼實現了:

namespace DailyPractice.UnityEx
{
public class UnityConfigEx
{
public static void Main() {
IUnityContainer myContainer = new UnityContainer();
UnityConfigurationSection section
= (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers[0].Configure(myContainer);
 
ILogService myServiceInstance = myContainer.Resolve<ILogService>

();
myServiceInstance.Write("oh,exception occured!");
}
}
}

執行結果為:

如果我們這樣更改配置節:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity" 

type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection

, Microsoft.Practices.Unity.Configuration" />
</configSections>
 
<unity>
<containers>
<container name="One">
<types>
<type type="DailyPractice.UnityEx.ILogService, 

DailyPractice.UnityEx"
mapTo="DailyPractice.UnityEx.CnsLogService, DailyPractice.UnityEx"/>
<!--<type type="DailyPractice.UnityEx.ILogService, 

DailyPractice.UnityEx"
mapTo="DailyPractice.UnityEx.DataLogService, 

DailyPractice.UnityEx"/>-->
</types>
<instances></instances>
<extensions></extensions>
</container>
</containers>
</unity>
</configuration>

執行結果為:

如果兩個都配置呢?那麼我們更改配置文件:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity" 

type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection

, Microsoft.Practices.Unity.Configuration" />
</configSections>
 
<unity>
<containers>
<container name="One">
<types>
<type type="DailyPractice.UnityEx.ILogService, 

DailyPractice.UnityEx" name="cnslogger"
mapTo="DailyPractice.UnityEx.CnsLogService, DailyPractice.UnityEx"/>
<type type="DailyPractice.UnityEx.ILogService, 

DailyPractice.UnityEx" name="datalogger"
mapTo="DailyPractice.UnityEx.DataLogService, 

DailyPractice.UnityEx"/>
</types>
<instances></instances>
<extensions></extensions>
</container>
</containers>
</unity>
</configuration>

修改程序代碼:

namespace DailyPractice.UnityEx
{
public class UnityConfigEx
{
public static void Main() {
IUnityContainer myContainer = new UnityContainer();
UnityConfigurationSection section
= (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers[0].Types[0].Configure(myContainer);
section.Containers[0].Types[1].Configure(myContainer);
 
IEnumerable<ILogService> myServiceInstances = 

myContainer.ResolveAll<ILogService>();
foreach (ILogService myServiceInstance in myServiceInstances) {
myServiceInstance.Write("haha, you have an exception 了吧!");
}
myContainer.Dispose();
}
}
}

運行結果:

這裡我強調一下:配置節name="cnslogger",在剛剛開始,我沒有指定了,結 果報錯如下

The entry ':DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx' has already been added. (D:\Project\ProjectEx\DailyPractice\UnityEx\bin\Debug\DailyPractice.Uni tyEx.vshost.exe.config line 22)

因為Unity有以下源碼

protected override object GetElementKey(ConfigurationElement 

element)
{
UnityTypeElement typeElement = (UnityTypeElement)element;
if (typeElement.Name == null)
{
return typeElement.TypeName;
}
 
return typeElement.Name + ":" + typeElement.TypeName;
}

如果不指定name,那麼兩個type在循環時就會導致GetElementKey都返回 了':DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx'結果,導致 實例化UnityConfigurationSection異常。

指定name,那麼這兩次實例化分別是:

cnslogger:DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx

datalogger:DailyPractice.UnityEx.ILogService, DailyPractice.UnityEx

UnityConfigurationSection即可實現正確實例化。

本節到此。

歡迎各位指教~~,謝謝

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved