運用Unity實現依賴注入[有參構造注入]


上一篇章講到關於使用Unity實現依賴注入的簡單功能,針對有博友提出關於有參構造注入的問題;

本文同樣通過一個實例來講解如何實現此功能,文中一些分層講解可以看上一文章(運用Unity實現依賴注入[結合簡單三層實例]),本文就不在重復;

1:首先我們在IAopBLL層新建一個IPropertyBLL類,我們增加的兩個屬性:name跟age

namespace IAopBLL
{
    public interface IPropertyBLL
    {
        string name { set; get; }

        int age { set; get; }

        void ShowInfo();

        void OutShowName();
    }
}

2:邏輯實現接口的代碼如下

using IAopDAL;
using IAopBLL;
using Command;
namespace AopBLL
{
    public class PropertyBLL:IPropertyBLL
    {
        IReadData bllServer = new UnityContainerHelp().GetServer<IReadData>();

        public string name { set; get; }

        public int age { get; set; }

        public PropertyBLL(string Name,int Age)
        {
            this.name = Name;
            this.age = Age;
        }

        public void ShowInfo()
        {
            Console.WriteLine(bllServer.ReadDataStr(name));
        }

        public void OutShowName()
        {
            Console.WriteLine("我是從構結函數得到Name的值:{0} 而Age的值:{1}",name,age);
        }
    }
}

*這邊有個要注意,因為Unity會自動使用參數最多的構造函數來進行創建對象,假如在這個類中有多個構造函數時,而我們要指定其中一個作為Unity進行創建對象則必需用到[InjectionConstructor],它是在Microsoft.Practices.Unity下面,要對DLL進行引用;比如下面我們使用到一個無參的構造函數讓Unity進行創建對象:

using IAopDAL;
using IAopBLL;
using Command;
using Microsoft.Practices.Unity;
namespace AopBLL
{
    public class PropertyBLL:IPropertyBLL
    {
        IReadData bllServer = new UnityContainerHelp().GetServer<IReadData>();

        public string name { set; get; }

        public int age { get; set; }

        public PropertyBLL(string Name,int Age)
        {
            this.name = Name;
            this.age = Age;
        }

        [InjectionConstructor]
        public PropertyBLL()
        {
        }

        public void ShowInfo()
        {
            Console.WriteLine(bllServer.ReadDataStr(name));
        }

        public void OutShowName()
        {
            Console.WriteLine("我是從構結函數得到Name的值:{0} 而Age的值:{1}",name,age);
        }
    }
}

3:接着我們修改公共層里的助手類,增加的方法public T GetServer<T>(Dictionary<string,object> parameterList)其中parameterList是我們用來定義構造函數集合;

using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using Microsoft.Practices.Unity.InterceptionExtension;
using Microsoft.Practices.Unity.InterceptionExtension.Configuration;
using System.Configuration;
using System.Reflection;

namespace Command
{
    public class UnityContainerHelp
    {
        private IUnityContainer container;
        public UnityContainerHelp()
        {
            container = new UnityContainer();
            UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
            container.LoadConfiguration(section, "FirstClass");
        }

        public T GetServer<T>()
        {
            return container.Resolve<T>();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ConfigName">配置文件中指定的文字</param>
        /// <returns></returns>
        public T GetServer<T>(string ConfigName)
        {
            return container.Resolve<T>(ConfigName);
        }

        /// <summary>
        /// 返回構結函數帶參數
        /// </summary>
        /// <typeparam name="T">依賴對象</typeparam>
        /// <param name="ConfigName">配置文件中指定的文字(沒寫會報異常)</param>
        /// <param name="parameterList">參數集合(參數名,參數值)</param>
        /// <returns></returns>
        public T GetServer<T>(Dictionary<string,object> parameterList)
        {
            var list = new ParameterOverrides();
            foreach (KeyValuePair<string, object> item in parameterList) 
            {
                list.Add(item.Key, item.Value);
            }
            return container.Resolve<T>(list);
        }
    }
}

4:配置文章里我們增加一個注冊依賴對象的節點

<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>
  </configSections>
  <unity xmlns="http://schemas.microsoft.com/practces/2010/unity">
    <container name="FirstClass">
      <register type="IAopBLL.IReadDataBLL,IAopBLL" mapTo="AopBLL.ReadDataBLL,AopBLL">
      </register>
      <register type="IAopBLL.IPropertyBLL,IAopBLL" mapTo="AopBLL.PropertyBLL,AopBLL"></register>
      <register type="IAopDAL.IReadData,IAopDAL" mapTo="AopOracelDAL.ReadDataDAL,AopOracelDAL"/>
    </container>
  </unity> 
</configuration>

5:接着看一下主程序代碼,其中Dictionary<string, object>存儲參數的名稱跟其對應的值,因為我們的值有可能是不同類型的所以使用object

using IAopBLL;
using Command;
namespace AopUnity
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, object> parameterList = new Dictionary<string, object>();
            parameterList.Add("Name", "踏浪帥2");
            parameterList.Add("Age", 27);
            IPropertyBLL bllProperty = new UnityContainerHelp().GetServer<IPropertyBLL>(parameterList);
            Console.WriteLine("--------運行方法ShowInfo()---------");
            bllProperty.ShowInfo();

            Console.WriteLine("--------運行方法OutShowName()---------");
            bllProperty.OutShowName();
            Console.WriteLine("-----------------------------------");
        }
    }
}


6:運行效果:

 

 

如果,您認為閱讀這篇博客讓您有些收獲,不妨點擊一下右下角的【推薦】按鈕。  因為,我的寫作熱情也離不開您的肯定支持。
 
感謝您的閱讀(因為源代碼現在我正接着寫Unity實現AOP的功能,所以將在實現功能后一起貼出)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM