ASP.NET MVC進階之路:依賴注入(Di)和Ninject

0X1 什麼是依賴注入

  依賴注入(Dependency Injection),是這樣一個過程:某客戶類只依賴於服務類的一個接口,而不依賴於具體服務類,因此客戶類只定義一個注入點。在程序運行過程當中,客戶類不直接實例化具體服務類實例,而是客戶類的運行上下文環境或專門組件負責實例化服務類,而後將其注入到客戶類中,保證客戶類的正常運行。sql

 

                                                      圖1數據庫

  如圖1所示,數據庫操做類DataManager中依賴的IDataBase的接口,而不是以來IDataBase的具體實現類,這樣的好處是可讓咱們的程序具備擴展性:不管咱們要使用SqlServer當咱們的數據庫操做類仍是用Mysql,咱們須要改動的地方都不多。函數

 

0X2 一個Demo理解Di

  咱們建立一個控制檯程序,並按照圖1中所標識的關係建立四個類。工具

 

public class DataManager
    {
        private IDataBase _database;
        public DataManager(IDataBase database)
        {
            this._database = database;
        }

        public void Add()
        {
            _database.Add();
        }

        public void Delete()
        {
            _database.Delete();
        }

        public void Update()
        {
            _database.Update();
        }

        public void Select()
        {
            _database.Select();
        }
    }

IDataBase接口

public interface IDataBase
    {
        string DbName { get; }
        void Select();
        void Update();
        void Delete();
        void Add();
    }
public class SqlServer : IDataBase
    {
        public string DbName
        {
            get
            {
                return "SqlServer";
            }
        }

        public void Add()
        {
            Console.WriteLine("Add in " + DbName);
        }

        public void Delete()
        {
            Console.WriteLine("Delete in " + DbName);
        }

        public void Select()
        {
            Console.WriteLine("Select in " + DbName);
        }

        public void Update()
        {
            Console.WriteLine("Update in " + DbName);
        }
    }

  

public string DbName
        {
            get
            {
                return "Mysql";
            }
        }

        public void Add()
        {
            Console.WriteLine("Add in " + DbName);
        }

        public void Delete()
        {
            Console.WriteLine("Delete in " + DbName);
        }

        public void Select()
        {
            Console.WriteLine("Select in " + DbName);
        }

        public void Update()
        {
            Console.WriteLine("Update in " + DbName);
        }

若是咱們要用Sqlserver做爲數據庫實現類的話,傳統寫法咱們要New Sqlserver,以下圖:this

項目早期使用的是Sqlserver數據庫沒問題,後來BOSS突然要改爲Mysql數據庫,你內心面一想,沒問題啊,無非就是把New後面的Sqlserver換成Mysql嘛,簡單。因而你就開始改,越改越不對勁,已經你已經發現當前項目已經有好幾十個地方用到New Sqlserver(),而剩餘的數量每每仍是未知的。這個時候你就在想,有沒有方法可讓我只須要改一個地方其餘地方不用動就能夠呢?答案是確定的,目前這種方法實現有不少種,最簡單的無非就是工廠模式。可是,今天,咱們不用工廠,咱們將使用Ninject來實現這種功能。spa

 

0X3 Ninject的使用

  Ninject是一個IOC容器,用來解決程序中組件的耦合問題,它的目的在於作到最少配置。其餘的的IOC工具過於依賴配置文件,須要使用assembly-qualified名稱來進行定義,庸長且複雜經常由於打錯字而破壞程序。這些是他的優勢,也是爲何要選擇它。3d

  

安裝Ninject

  打開Nuget程序包管理控制檯輸入「Install-Package Ninject」便可安裝Ninject。code

  

 

Ninject使用步驟

  咱們通常會在程序啓動的入口來建立Ninject的對象負責類型的註冊。server

1  static void Main(string[] args)
2         {
3             //實例化Ninject對象
4             IKernel Kerner = new StandardKernel();
5         }

  使用Ninject對象分兩個步驟,第一步是把接口對象或者說被依賴的對象(IDataBase)綁定到Ninject中,而後在爲其綁定對應的實例類型(若是要使用SqlServer則就綁定SqlServer)。對象

 //實例化Ninject對象
 IKernel Kerner = new StandardKernel();
 //綁定對象
 Kerner.Bind<IDataBase>().To<SqlServer>();

  第二步則是經過Ninject的Get方法獲取IDataBase的實現類

 var Db = Kerner.Get<IDataBase>(); //因爲上面IDataBase綁定的是SqlServer類型,因此這裏獲取的類型是SqlServer

  上面的代碼你們可能體會不到使用Ninject的好處,也沒有體會到依賴注入的奧妙所在。依賴注入大體分爲三類:接口注入,函數注入,屬性注入。咱們來經過一個例子來演示屬性注入。

  咱們增長一個IShowDBInfo的接口類,其有一個Show方法。而後添加一個Show類實現IShowDBInfo接口:

 

 public class Show1 : IShowDBInfo
    {
        public void Show()
        {
            Console.WriteLine(this.GetType().FullName);
        }
    }

    咱們給DataManager添加一個IShowDBInfo屬性並增長一個Show()方法:

 public class DataManager
    {
        private IDataBase _database;
        private IShowDBInfo _showDbInfo;
        public DataManager(IDataBase database, IShowDBInfo ishowdbinfo)
        {
            this._database = database;
            _showDbInfo = ishowdbinfo;
        }
       //省略Add,Updata,Delete,Select方法
        public void Show()
        {
            _showDbInfo.Show();
        }
    }     

  在應用程序啓動的時候註冊IShow類和註冊DataManager類並啓動程序:

 static void Main(string[] args)
        {
            //實例化Ninject對象
            IKernel Kerner = new StandardKernel();
            //綁定對象
            Kerner.Bind<IDataBase>().To<SqlServer>();
            Kerner.Bind<IShowDBInfo>().To<Show1>();
            Kerner.Bind<DataManager>().ToSelf();
            var dataManager=Kerner.Get<DataManager>();
            dataManager.Show();
            Console.Read();
        }

  從上代碼以及運行結果來看,咱們只須要在向Ninject實例裏面註冊對象,而後在其餘類中使用的時候咱們只須要定義接口就能夠了,並不須要實例化對象。這樣作的話可使咱們和其餘層進行鬆耦合。

相關文章
相關標籤/搜索