2012-01-10 19 views
4

私は依存関係注入(DI)の基礎を学びたいと考えています。この目的のために、私はC#コンソールアプリケーションの構築を通して、DIのためにNinjectを使用する方法を示すチュートリアルを開始しました。ninjectとc#.netで条件付き依存関係注入を実装する

本アプリケーションは、基本的に、さまざまな計算方法を使用してショッピングカート内のアイテムの価値を計算できるようにすることを目的としています。

アプリケーション内のクラスは次のとおりです。

  • 製品のコレクション、そのメソッドのValueProductsを要求
  • A ValueCalculatorインタフェース周りのような単純なラッパーとして機能するシンプルな製品モデル
  • 2ショッピングカートクラスカート内のアイテムの合計を返します
  • ValueCalculatorインターフェイスの2つの別々の実装(反復およびLINQアプローチ)

ShoppingCartオブジェクトにLinqValueCalculatorが注入され、ShoppingCartTwoオブジェクトにIterativeValueCalulatorが注入されるように、.WhenInjectedTo拡張メソッドを介して条件付き注入を使用しようとしました。ただし、どちらの場合も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(); 
    } 
} 
} 
+0

チュートリアルへのリンクはありますか? – fordareh

答えて

5

、以下を参照してくださいコード私はあなたの問題はそれだと思う: -

ninjectKernel.Get<IValueCalculator>() 

それはあなたのコンストラクターに渡さ前に評価しています。

つまり、バインディングコンテキスト外で呼び出されています。

オブジェクトを新しく作成する代わりに、カーネルを使用してオブジェクトインスタンスを取得します。

var shopCartTwo = ninjectKernel.Get<ShoppingCartTwo>(); 

パラメータを一切渡していないことに注意してください。 Ninjectはコンストラクタシグネチャを調べ、未解決の依存関係が存在するかどうかを調べ、適切なコンテキストバインディングを使用します。

+0

お返事ありがとうございます。 – bradmbow

+0

お返事ありがとうございます。私はこれを試し、それが十分に働いたと確信しているどのように**条件付き**それはですか?すなわち、私はShoppingCartTwoオブジェクトを明示的に求めなければなりませんでした...それで、インタフェースからクラスを解決するように要求するのではなく、注入を含むクラスのインスタンスをninjectに尋ねるという考えはありますか? – bradmbow

+0

より実現されたソリューションでは、ショッピングカートオブジェクトのいずれかの具体的な実装を扱っていない可能性があります。あなたはIShoppingCart(これを実装するShoppingCartとShoppingCartTwoと一緒に)を求めるでしょう。どの状況になるのかを示す文脈的拘束力があると思われます。これが解決されると、ninjectは使用するIValueCalculatorの実装を知ります。 あなたの最終的なプロジェクトタイプはどのようなものでしょうか? –

関連する問題