依賴注入之Ninject架構

來源:互聯網
上載者:User

這次要介紹的是一個非常不錯的DI(即依賴注入)架構,就是Ninject,通過使用此架構,可以非常方便地實現DI。不過在介紹此架構之前,先讓我們再來看看到底為什麼要使用依賴注入和其具體實現吧。

請大家先看以下代碼,我們先建立最基本的產品類,然後添加一個價格計算介面和一個實現此介面的類:

    //產品類
    public class Product
    {
        public int ProductID { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
        public string Category { set; get; }
    }
    //價格計算介面
    public interface IValueCalculator
    {
        decimal ValueProducts(params Product[] products);
    }
    //實現價格計算介面
    public class LinqValueCalculator : IValueCalculator
    {
        public decimal ValueProducts(params Product[] products)
        {
            return products.Sum(p => p.Price);
        }
    } 

接下來再建立購物車類,然後將以上介面添加進去:

  public class ShoppingCart
    {
        private IValueCalculator calculator;

        public ShoppingCart(IValueCalculator calcParam)
        {
            calculator = calcParam;
        }

        public decimal CalculateStockValue()
        {
            // 定義和設定產品資訊
            Product[] products =
            {
                        new Product() {  Name = "Kayak", Price  = 275M},
                        new Product() {  Name = "Lifejacket",  Price = 48.95M}, 
                        new Product() {  Name = "Soccer ball",  Price = 19.50M}, 
                        new Product() {  Name = "Stadium", Price  = 79500M}
            };
            // 計算總價格 
            decimal totalValue = calculator.ValueProducts(products);

            // 返回計算結果 
            return totalValue;
        }
    }

 

從以上代碼可看出,ShoppingCart和LinqValueCalculator都依賴於IValueCalculator介面,但ShoppingCart和LinqValueCalculator之間並沒有直接關係,甚至ShoppingCart並不知道LinqValueCalculator的存在,這樣的好處也顯而易見,就是LinqValueCalculator可以隨時更換而不會影響到ShoppingCart裡的代碼,因此也達到了松耦合的效果了。

以下是上面幾個類的關係圖:

OK,現在看看如何結合Ninject來使用以上代碼。首先要為你的項目添加Ninject引用,在項目名稱裡點擊右鍵,然後選擇“Add PackageLibrary Reference”,然後只需在搜尋方塊裡輸入 ninject ,這時就可看到下面的挑選清單裡出現了 Ninject的項目了,直接選擇安裝即可

 

為了方便示範,只需建立一個控制台項目即可。要使用Ninject,可直接調用IKernel介面,代碼如下:

    class Program
    {
        static void Main(string[] args)
        {
            IKernel ninjectKernel = new  StandardKernel();
            //綁定介面到實作類別裡
            ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator<();
        }
    }

以上代碼將介面與實作類別綁定起來了,然後再添加以下代碼以實現ShoppingCart類:

   // 擷取實現的介面
  IValueCalculator calcImpl = ninjectKernel.Get<IValueCalculator>();
  // 建立執行個體注入到 ShoppingCart
  ShoppingCart cart = new  ShoppingCart(calcImpl);
  // 執行計算功能以輸出結果
  Console.WriteLine("Total: {0:c}", cart.CalculateStockValue());

可能大家會感覺這樣使用還不如直接調用來得方便啊,如果不使用 Ninject ,我們只需直接使用:

 ShoppingCart cart =  new ShoppingCart(new LinqValueCalculator());

這樣就可以了,不是方便很多嗎?為什麼還要用Ninject寫這麼多代碼呢?
嗯,以上其實只是一個最簡單的為了示範的代碼,如果隨著複雜的多層介面的注入增加的話,就可以馬上體現出Ninject的效率和好處了!

請繼續看以下代碼,我們再添加一個新的折扣介面:

 //添加折扣介面
    public interface IDiscountHelper
    {
        decimal ApplyDiscount(decimal totalParam);
    }

    //實現不同的折扣
    public class DefaultDiscountHelper : IDiscountHelper
    {

        public decimal ApplyDiscount(decimal totalParam)
        {
            return (totalParam - (10m / 100m * totalParam));
        }
    }

    //為之前的價格功能裡添加折扣功能,實現折扣介面
    public class LinqValueCalculator : IValueCalculator
    {
        private IDiscountHelper discounter;

        public LinqValueCalculator(IDiscountHelper discountParam)
        {
            discounter = discountParam;
        }

        public decimal ValueProducts(params Product[] products)
        {
            return discounter.ApplyDiscount(products.Sum(p => p.Price));
        }
    }

現在我們又多了一層注入的介面了,但使用Ninject的話就非常方便,只需添加多一行代碼就可以了:

    ...
  IKernel ninjectKernel = new StandardKernel(); 
 
  ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
  //這是為新介面添加的,其他代碼均不需改動
  ninjectKernel.Bind<IDiscountHelper>().To<DefaultDiscountHelper>();
 
  // 擷取實現的介面 
  IValueCalculator calcImpl = ninjectKernel.Get<IValueCalculator>();
  ShoppingCart cart = new  ShoppingCart(calcImpl);
  Console.WriteLine("Total: {0:c}", cart.CalculateStockValue());
  ...

隨著代碼介面的複雜性增多,就可以體現出Ninject的好處了 

 

ASP.NET MVC中應用:

namespace NinjectDemo.Infrastructure
{
    public class NinjectControllerFactory : DefaultControllerFactory
    {
        private IKernel ninjectKernel;
        public NinjectControllerFactory()
        {
            ninjectKernel = new StandardKernel();
            AddBindings();
        }
        protected override IController GetControllerInstance(RequestContext requestContext,
        Type controllerType)
        {
            return controllerType == null
            ? null
            : (IController)ninjectKernel.Get(controllerType);
        }
        private void AddBindings()
        {
            // put additional bindings here
            ninjectKernel.Bind<IProductRepository>().To<FakeProductRepository>();
        }
    }
}

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
    ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
}

 

引用:http://www.coderblog.in/2011/09/using-ninject-for-di.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.