Ninject


一、為什么要使用依賴注入框架

  依賴注入框架也叫IoC容器。它的作用使類與類之間解耦

  我們看看為什么要用依賴注入框架,舉個幾個梨子:

  1,高度耦合的類

  

      有一個Order類,Order類是用於訂單操作的,DataAccess使用的sqlserver的方式查詢訂單。看看代碼:

public class Order
    {
        private DataAccess dataAccess = new DataAccess();
        public string QueryOrder()
        {
            return dataAccess.QueryOrder();
        }
    }

    public class DataAccess
    {
        public string QueryOrder()
        {
            return "sqlserver查詢Order";
        }
    }

 

  看到這兩個類(Order,DataAccess),它們出現了高度耦合。如果產品汪突然狂犬病大發讓我們換成MySql方式查詢,我們不得不修改Order類的private DataAccess data = new DataAccess() 和DataAccess的QueryOrder方法。這里違反了開放封閉原則(對擴展開放,對修改關閉),當然一個項目不只只有訂單(Order)操作,還有購物車、產品等等操作,那改動起來將會是一場噩夢。

 

  2,使用依賴倒轉原則來改進

  依賴倒轉原則口訣:高層次模塊不應該依賴於低層次模塊,要依賴抽象,不要依賴具體。

  口訣聽着很繞口,其實理解起來並不難,看下面的類圖,Order相當於是高層模塊,SqlServerData和MySqlData相當於底層模塊,高層模塊依賴於接口,所以可以隨時更換底層模塊

  

  我們現在把DataAccess抽象為接口,使SqlServerData和MySqlData實現IDataAccess

    public class Order
    {
        private IDataAccess dataAccess = new MySqlData();
        public string QueryOrder()
        {
            return dataAccess.QueryOrder();
        }
    }


    public interface IDataAccess
    {
        string QueryOrder();
    }


    public class SqlServerData : IDataAccess
    {
        public string QueryOrder()
        {
            return "sqlserver查詢Order";
        }
    }

    public class MySqlData : IDataAccess
    {
        public string QueryOrder()
        {
            return "MySql查詢Order";
        }
    }

  現在我們高層模塊依賴於接口,如果產品汪再叫我們換Oracle數據庫,我們就可以再添加一個OracleData類,然后實現IDataAccess接口,然后在Order類中的private IDataAccess dataAccess = new MySqlData()改為private IDataAccess dataAccess = new OracleData()。雖然改動的地方減少了,但是我們還是修改了類。可是我們並不希望修改類,就可以更換數據訪問,這就需要解耦,需要用到Ioc容器,我們的Ninject終於該出場了,出場費還不低哦!

 

二、實戰Ninject

  

 

1,使用注冊機制

  首先安裝一個Ninject的Dll,我們用NuGet安裝。

  ①反鍵項目引用,選中管理NuGet程序包

  

  ②搜索Ninject,點擊安裝

  

  ③代碼實現(只實現Order類操作,Product類操作與Order類一致)

  IDataAccess:

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

namespace RegisterNinject
{
    public interface IDataAccess
    {
        string QueryOrder();
    }
}

  MySqlDataOrder:

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

namespace RegisterNinject
{
    public class MySqlDataOrder : IDataAccess
    {
        public string QueryOrder()
        {
            return "MySql查詢Order";
        }
    }
}

  SqlServerDataOrder:

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

namespace RegisterNinject
{
    public class SqlServerDataOrder : IDataAccess
    {
        public string QueryOrder()
        {
            return "sqlserver查詢Order";
        }
    }
}

  Register:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject; //引入命名空間
namespace RegisterNinject
{
    public class Register
    {
        private StandardKernel _kernel = new StandardKernel();
        // 在這里注冊
        public Register()
        {
            _kernel.Bind<IDataAccess>().To<MySqlDataOrder>();
            //_kernel.Bind<IDataAccess>().To<SqlServerDataOrder>();
            //_kernel.Bind<IDataProduct>().To<SqlServerDataProduct>();
        }

        //獲取
        public TInterface Get<TInterface>()
        {
            return _kernel.Get<TInterface>();
        }

        public void Dispose()
        {
            _kernel.Dispose();
        }
    }
}

  Order:

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

namespace RegisterNinject
{
    public class Order
    {
        private Register reg = new Register();
        public string QueryOrder()
        {
            return reg.Get<IDataAccess>().QueryOrder();
        }

    }
}

 

  這樣,媽媽再也不用擔心我換數據庫了。如果產品汪再讓我們換回sqlserver數據庫[神經病](小插曲:換數據庫是舉的例子,Ioc容器的意義是讓類與類之間解耦的,不是換數據庫用的!),我們只需要在Register類中的構造函數中修改注冊即可。

  有人說,"你還是修改了類呀!"。Register類的定位不一樣,他是一個公共類,專門提供注冊機制的。如果不去要修改類,就能完成換數據庫,那就要引入新的概念———熱插拔技術。

  

2,使用Xml文件(熱插拔)

  現在我們用xml文件的方式,動態的更換接口。我們需要建一個xml文件。把他放在項目中。

  Register.xml

<?xml version="1.0" encoding="utf-8" ?> 
<module name="register">
  <bind service="XmlNinject.IDataAccess,XmlNinject" to="XmlNinject.SqlServerDataOrder,XmlNinject"/>
</module>

 

  注意:module元素,name屬性,bind元素,service屬性,to屬性為規定的元素屬性,不能寫成別的。格式也要正確。

  然后更改下Register

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject; //引入命名空間
using Ninject.Extensions.Xml;//引入命名空間
namespace XmlNinject
{
    public class Register
    {
        private StandardKernel _kernel = new StandardKernel();

        // 以后這里就不用更改這里了,只需要該xml文件就可以了
        public Register()
        {
            var settings = new NinjectSettings() { LoadExtensions = false };
            _kernel = new StandardKernel(settings, new XmlExtensionModule());
            _kernel.Load("Xml/Register.xml");
        }

        //獲取
        public TInterface Get<TInterface>()
        {
            return _kernel.Get<TInterface>();
        }

        public void Dispose()
        {
            _kernel.Dispose();
        }
    }
}

   以后要更換接口,直接更改xml文件就可以了。

   源碼下載http://pan.baidu.com/s/1sjJXVrv  

 


免責聲明!

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



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