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


0X1 什么是依賴注入

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

 

                                                      圖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,如下圖:

項目早期使用的是Sqlserver數據庫沒問題,后來BOSS忽然要改成Mysql數據庫,你心里面一想,沒問題啊,無非就是把New后面的Sqlserver換成Mysql嘛,簡單。於是你就開始改,越改越不對勁,已經你已經發現當前項目已經有好幾十個地方用到New Sqlserver(),而剩余的數量往往還是未知的。這個時候你就在想,有沒有方法可以讓我只需要改一個地方其他地方不用動就可以呢?答案是肯定的,目前這種方法實現有很多種,最簡單的無非就是工廠模式。但是,今天,我們不用工廠,我們將使用Ninject來實現這種功能。

 

0X3 Ninject的使用

  Ninject是一個IOC容器,用來解決程序中組件的耦合問題,它的目的在於做到最少配置。其他的的IOC工具過於依賴配置文件,需要使用assembly-qualified名稱來進行定義,庸長且復雜常常因為打錯字而破壞程序。這些是他的優點,也是為什么要選擇它。

  

安裝Ninject

  打開Nuget程序包管理控制台輸入“Install-Package Ninject”即可安裝Ninject。

  

 

Ninject使用步驟

  我們一般會在程序啟動的入口來創建Ninject的對象負責類型的注冊。

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實例里面注冊對象,然后在其他類中使用的時候我們只需要定義接口就可以了,並不需要實例化對象。這樣做的話可以使我們和其他層進行松耦合。


免責聲明!

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



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