[英]Implementing conditional dependency injection with ninject and c#.net
我正在嘗試學習依賴注入(DI)的基礎知識。 為此,我已經開始了一個教程,演示如何通過構建C#控制台應用程序來使用Ninject進行DI。
該應用程序本質上旨在能夠使用不同的計算方法計算購物車中的項目的價值。
應用程序中的類是:
我試圖通過.WhenInjectedTo擴展方法使用條件注入,這樣ShoppingCart對象就會注入一個LinqValueCalculator,而ShoppingCartTwo對象會注入一個IterativeValueCalulator。 但是, 在這兩種情況下都會注入LinqValueCalculator。
見下面的代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject;
namespace NinjectDemo
{
// a simple product model
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; }
}
// calculator interface
public interface IValueCalculator
{
decimal ValueProducts(params Product[] products);
}
// a specific implementation of the IValueCalculator using LINQ
public class LinqValueCalculator : IValueCalculator
{
public LinqValueCalculator() {}
public decimal ValueProducts(params Product[] products)
{
return (products.Sum(p => p.Price));
}
}
// another implementation of IValueCalculator using iteration
// (*2 is to so that it returns a different result to LinqValueCalculator)
public class IterativeValueCalculator : IValueCalculator
{
public IterativeValueCalculator() {}
public decimal ValueProducts(params Product[] products)
{
decimal totalValue = 0;
foreach (Product p in products)
{
totalValue += (p.Price) * 2;
}
return totalValue;
}
}
// a shopping cart modelling a collection of products
public class ShoppingCart
{
protected IValueCalculator calculator;
protected Product[] products;
public ShoppingCart(IValueCalculator calcParam)
{
calculator = calcParam;
// define the set of products to sum
products = new []
{
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}
};
}
public virtual decimal CalculateStockValue()
{
// calculate the total value of the products
decimal totalValue = calculator.ValueProducts(products);
// return the result
return totalValue;
}
}
// another, different, shopping cart
public class ShoppingCartTwo
{
protected IValueCalculator calculator;
protected Product[] products;
public ShoppingCartTwo(IValueCalculator calcParam)
{
calculator = calcParam;
// define the set of products to sum
products = new[]
{
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}
};
}
public virtual decimal CalculateStockValue()
{
// calculate the total value of the products
decimal totalValue = calculator.ValueProducts(products);
// return the result
return totalValue;
}
}
class Program
{
static void Main(string[] args)
{
IKernel ninjectKernel = new StandardKernel();
// define the bindings
ninjectKernel.Bind<IValueCalculator>().To<IterativeValueCalculator> ().WhenInjectedInto<ShoppingCartTwo>();
ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
// create the carts and inject the dependency
ShoppingCart cart = new ShoppingCart(ninjectKernel.Get<IValueCalculator>());
ShoppingCartTwo cartTwo = new ShoppingCartTwo(ninjectKernel.Get<IValueCalculator>());
// perform the calculation and write out the result
Console.WriteLine("Total: {0:c}", cart.CalculateStockValue());
Console.WriteLine("Total: {0:c}", cartTwo.CalculateStockValue());
Console.Read();
}
}
}
我認為你的問題是: -
ninjectKernel.Get<IValueCalculator>()
在它被傳遞到你的構造函數之前進行評估。
即它在其綁定上下文之外被調用。
不要自己新建對象,而是使用內核來獲取對象實例。
var shopCartTwo = ninjectKernel.Get<ShoppingCartTwo>();
請注意,您根本沒有傳遞參數。 Ninject將查看構造函數簽名,確定存在未解析的依賴關系,並使用適當的上下文綁定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.