1. 程式人生 > >C#/.NET IOC框架——Unity容器基礎入門

C#/.NET IOC框架——Unity容器基礎入門

C# IOC容器Unity

控制反轉(Inversion of Control,英文縮寫為IoC)是一個重要的面向物件程式設計的法則來削減計算機程式的耦合問題,也是輕量級的Spring框架的核心。 控制反轉一般分為兩種型別,依賴注入(Dependency Injection,簡稱DI)和依賴查詢(Dependency Lookup)。依賴注入應用比較廣泛。

unity元件網址:http://unity.codeplex.com/

1. 先載入相關依賴項:NuGet

!!關鍵一點必須注意!!

用Unity.Interception 5.1.0(別用最新的,一大堆神BUG)

總共需要以下四個,直接安裝

2. 問題描述

先準備幾個類

	/// <summary>
	/// 班級介面
	/// </summary>
	public interface IClass
	{
		string ClassName { get; set; }

		void ShowInfo();
	}
	/// <summary>
	/// 計科班
	/// </summary>
	public class CbClass : IClass
	{
		public string ClassName { get; set; }

		public void ShowInfo()
		{
			Console.WriteLine("計科班:{0}", ClassName);
		}
	}
	/// <summary>
	/// 電商班
	/// </summary>
	public class EcClass : IClass
	{
		public string ClassName { get; set; }

		public void ShowInfo()
		{
			Console.WriteLine("電商班:{0}", ClassName);
		}
	}

很多人初始化例項的時候就比如這樣

CbClass cbclass = new CbClass();

使用依賴倒置原則的話則是這樣

IClass class = new CbClass();

好一點的就再建個簡單工廠封裝一下

var class = Factory.CreateClass();

3. 問題解決

但類一旦多了以後,每增加類你都得修改工廠,這樣就變得很繁雜了,這裡使用依賴注入解決這個問題

 public static void ContainerCodeTest1()
{
    IUnityContainer container = new UnityContainer();
    
    //預設註冊(無命名),如果後面還有預設註冊會覆蓋前面的
    container.RegisterType<IClass, CbClass>();
  
    //命名註冊
    container.RegisterType<IClass, EcClass>("ec");

    //解析預設物件
    IClass cbClass = container.Resolve<IClass>();
    cbClass.ShowInfo();

    //指定命名解析物件
    IClass ecClass = container.Resolve<IClass>("ec");           
    ecClass.ShowInfo();

    //獲取容器中所有IClass的註冊的已命名物件
    IEnumerable<IClass> classList = container.ResolveAll<IClass>();
    foreach (var item in classList)
    {
        item.ShowInfo();
    }
}

4. 使用配置檔案解決

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>
  </configSections>
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <!--定義類型別名-->
    <aliases>
      <add alias="IClass" type="ConsoleApplication1.UnityDemo.IClass,ConsoleApplication1" />
      <add alias="CbClass" type="ConsoleApplication1.UnityDemo.CbClass,ConsoleApplication1" />
      <add alias="EcClass" type="ConsoleApplication1.UnityDemo.EcClass,ConsoleApplication1" />
    </aliases>
    <!--容器-->
    <container name="FirstClass">
      <!--對映關係-->
      <register type="IClass"  mapTo="CbClass"></register>
      <register type="IClass" name="ec" mapTo="EcClass"></register>
    </container>
  </unity>
</configuration>

資料解析方法

public static void ContainerConfigurationTest1()
{
    IUnityContainer container = new UnityContainer();
    string configFile = "http://www.cnblogs.com/UnityDemo/Constructor/Unity.config";
    var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = configFile };
    //從config檔案中讀取配置資訊
    Configuration configuration =
        ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
    //獲取指定名稱的配置節
    UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

    //載入名稱為FirstClass 的container節點
    container.LoadConfiguration(section, "FirstClass");

   //解析預設物件
    IClass cbClass = container.Resolve<IClass>();
    cbClass.ShowInfo();

    //指定命名解析物件
    IClass ecClass = container.Resolve<IClass>("ec");           
    ecClass.ShowInfo();

    //獲取容器中所有IClass的註冊的已命名物件
    IEnumerable<IClass> classList = container.ResolveAll<IClass>();
    foreach (var item in classList)
    {
        item.ShowInfo();
    }
}

文章具體實現程式碼參考:http://www.cnblogs.com/qqlin/