Я пытаюсь изучить основы внедрения зависимостей (DI). С этой целью я предпринял учебник, который демонстрирует использование Ninject для DI через создание консольного приложения C #.
Приложение, по сути, нацелено на то, чтобы иметь возможность рассчитывать стоимость товаров в корзине, используя различные методы расчета.
Классы в приложении:
- Простая модель товара
- два класса корзины покупок, которые действуют как простые обертки вокруг коллекции Товаров
- Интерфейс ValueCalculator, который требует метод ValueProducts, который возвращает некоторое количество товаров в корзинах
- Две отдельные реализации интерфейса ValueCalculator (итеративный подход и подход LINQ)
Я попытался использовать условное внедрение с помощью метода расширения .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();
}
}
}