經過反射實現IOC功能

這段時間園子裏有很多介紹IOC組件的文章,因爲本身也一直在學習IOC的各類組件,及IOC的思想,常見的IOC組件不少:AutoFac、Ninject、Utity包括.NET自帶的MEF等。因爲今天週六,女友去加班了(也是一枚標準的程序媛,作java開發),閒來沒事,本身就想着根據反射能夠本身寫一個簡易的IOC組件。IOC組件說白了就是根據反射實例化對應的接口。廢話很少說,開始說說個人解決方案。java

一、項目結構圖:web

  • IOCTest爲web MVC項目。
  • Common 經過配置文件實例化對應的接口
  • IBLL定義的接口
  • BLL實現接口

二、引用app

  1. IOCTest項目引用IBLL、Common項目,不能引用BLL項目,這樣就使IOCTest項目只依賴接口。
  2. BLL項目引用IBLL並實現接口
  3. 修改BLL項目dll生成路徑,使其DLL生成到IOCTest項目的Bin目錄下,以下圖設置

 

三、下面咱們來看具體的實現函數

(1)在IBLL層的IHelloWord.cs類中咱們定義一個接口,代碼以下學習

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IBLL
{
  public  interface IHelloWord
    {
      string SayHello(string Name);
    }
}

 

(2)BLL層實現接口測試

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IBLL;

namespace BLL
{
    public class HelloWord:IHelloWord
    {
        #region IHelloWord 成員

        public string SayHello(string Name)
        {
            return  "Hello_"+Name;
        }

        #endregion
    }
  
}

 

(3)在IOCTest 項目的根目錄Web.config下作以下配置(把HelloWordIHelloWord對應起來):spa

  <appSettings>
    <add key="IBLL.IHelloWord" value="BLL,BLL.HelloWord"/>
  </appSettings>
 說明:
  key值爲接口的全稱(命名空間+類名),value值爲實現接口的類,兩部分組成,逗號前面爲生成的dll名稱,逗號後面爲類名全稱(命名空間+類名)。

 

(4)Common 項目的IOCReflecter.cs類根據配置文件獲取對應接口的實例化對象,代碼實現以下code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Reflection;
using System.Configuration;

namespace Common
{
    public class IOCReflecter
    {
        private static Hashtable s_type=null;
        static IOCReflecter()
        {
            s_type = new Hashtable();
        }

        public static T CreateIntance<T>()
        {
            Type t=typeof(T);//key
            Type type = s_type[t] as Type;//value
            if (type == null)
            {
                string[] AssemblyInfos = ConfigurationManager.AppSettings[t.FullName].Split(',');
                type = Assembly.Load(AssemblyInfos[0]).GetType(AssemblyInfos[1]);
                s_type.Add(t, type);
            }
            return (T)CreateObject(type) ;
        }

        /// <summary>
        /// 根據typeName獲取Type對象
        /// </summary>
        /// <param name="typeName"></param>
        /// <returns></returns>
        public static Type GetType(string typeName)
        {
            if (string.IsNullOrWhiteSpace(typeName))
            {
                return null;
            }
            return Type.GetType(typeName);
        }
        /// <summary>
        /// 獲取對象
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        private static object CreateObject(Type t)
        {
            if (t == null)
            {
                return null;
            }
            //查找沒有參數的構造函數
            //若是須要初始化帶參數的構造函數 t.GetConstructors() 獲取全部的構造函數 ,it.GetParameters()獲取構造函數全部的參數,
            ConstructorInfo NonParameterConstructors= t.GetConstructors().Where(it=>it.GetParameters().Length==0).FirstOrDefault();
            if (NonParameterConstructors == null)
            {
                throw new Exception( t.FullName+"必須有一個無參數或默認的構造函數");
            }
            //調用數構造函數建立對象
            return t.InvokeMember(null, BindingFlags.CreateInstance, null, null, null);
        }
    }
}

(5)測試對象

在IOCTest項目Controllers中添加HomeController.cs文件,代碼以下blog

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using IBLL;
using Common;

namespace IOCTest.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            //獲取實例化對象
            IHelloWord hello = IOCReflecter.CreateIntance<IHelloWord>();
            ViewBag.Message = hello.SayHello("eric");
            return View();
        }

    }
}

 

@{
    ViewBag.Title = "Index";
}

<h2>@ViewBag.Message </h2>

最後上一張截圖:

到此結束,準備收拾收拾下樓去吃飯,下午去國家圖書館看書,後續把AutoFac、Ninject、Utity總結一下,感受Ninject比較好用,有興趣的同窗能夠研究一下。

天天學習一點點,天天進步一點點。

相關文章
相關標籤/搜索