2011-12-07 10 views
5

背景

上の必要性のヘルプには、それを使用する方法を、私はすべての3つのIOC技術の例を作成するIOCの私の理解を向上させるために、サードパーティ製のフレームワークを使用することなくインターフェイス注入が可能です。私はコンストラクタインジェクションの基本的な例があると思いますが、セッターとインターフェイスインジェクションに苦しんでいます。カスタムIOCコンテナ2/3タイプ

私の質問

あなたは地上からのインタフェースとセッター・インジェクションを書いて取り組むアプローチだろうか

ここに私の考えがあります、私が正しい軌道にいるかどうか教えてください。

インタフェース注入:解決オブジェクトを通して

  1. ループを実装するインターフェイスを関連付けるinterfaceDependencyMapのいくつかの並べ替えを定義
  2. interfaceDependencyMap
  3. に実装されているものインターフェースを確認し、コンストラクタインジェクションを使用してインスタンス化。
  4. はコンストラクタ・インジェクションで初期化されたオブジェクトに適切なプロパティを割り当てinterfaceDependencyMap
  5. を使用して実装を解決
セッターインジェクション

:解決オブジェクトを通じて

  1. ループ
  2. いくつかの定義コンストラクタ・インジェクションを使用してインスタンス化並べ替えsetterInjectionMap
  3. 期待されるパラメータをから解決するMETHODINFOは、コンストラクタのマッピング
  4. が解決パラメータオブジェクトに

を渡すsetterメソッドを呼び出して使用すると、ここで私はこれまでのコンストラクタ・インジェクションのため

public class Program 
{ 
    static void Main(string[] args) 
    { 
     // 
     //instead of doing this: 
     // 
     //ICreditCard creditCard = new Visa(); 
     //var customer = new Customer(creditCard); 
     //customer.Charge(); 


     var resolver = new Resolver(); 

     //map the types in the container 
     resolver.Register<Customer, Customer>(); 
     resolver.Register<ICreditCard, Visa>(); 

     //because the customer constructor has an ICreditCard parameter 
     //our container will automatically instantiate it recursively 
     var customer = resolver.Resolve<Customer>(); 

     customer.Charge(); 

    } 
} 

public interface ICreditCard 
{ 
    string Charge(); 
} 

public class Visa : ICreditCard 
{ 
    public string Charge() 
    { 
     return "Charging Visa"; 
    } 
} 

public class MasterCard : ICreditCard 
{ 
    public string Charge() 
    { 
     return "Charging MasterCard"; 
    } 
} 

public class Customer 
{ 
    private readonly ICreditCard _creditCard; 

    public Customer(ICreditCard creditCard) 
    { 
     this._creditCard = creditCard; 
    } 

    public void Charge() 
    { 
     _creditCard.Charge(); 
    } 
} 


public class Resolver 
{ 
    private Dictionary<Type, Type> dependencyMap = new Dictionary<Type, Type>(); 

    public T Resolve<T>() 
    { 
     return (T) Resolve(typeof (T)); 
    } 

    private object Resolve(Type typeToResolve) 
    { 
     Type resolvedType = null; 

     try 
     { 
      resolvedType = dependencyMap[typeToResolve]; 
     } 
     catch 
     { 
      throw new Exception(string.Format("could not resolve type {0}", typeToResolve.FullName)); 
     } 

     var firstConstructor = resolvedType.GetConstructors().First(); 
     var constructorParameters = firstConstructor.GetParameters(); 
     if (constructorParameters.Count() == 0) 
      return Activator.CreateInstance(resolvedType); 

     IList<object> parameters = constructorParameters.Select(parameterToResolve => Resolve(parameterToResolve.ParameterType)).ToList(); 

     return firstConstructor.Invoke(parameters.ToArray()); 
    } 

    public void Register<TFrom, TTo>() 
    { 
     dependencyMap.Add(typeof (TFrom), typeof (TTo)); 
    } 
} 
+5

質問は何ですか? – svick

+0

これを再オープンする方法はありますか? –

+0

@EricRomanowski:なぜ質問が終了したのかについては、以下の理由を参照してください。あなたの質問でその理由に取り組むことができれば、他の人は、それがSOに関する質問の基準を満たしていると感じていると仮定して、再開した投票をすることができます。 – casperOne

答えて

3

は、あなたが探しているもののこの種ですしているものです?

class Container 
{ 
    class Registration 
    { 
     public Type RegistrationType; 
     public Func<Container, object> Resolver; 
    } 

    List<Registration> registrations = new List<Registration>(); 

    public object Resolve(Type type) 
    { 
     return registrations 
      .First(r => type.IsAssignableFrom(r.RegistrationType)) 
      .Resolver(this); 
    } 

    public T Resolve<T>() 
    { 
     return (T)Resolve(typeof(T)); 
    } 

    public void Register<T>(Func<Container, T> registration) where T : class 
    { 
     registrations.Add(new Registration() 
     { 
      RegistrationType = typeof(T), 
      Resolver = registration 
     }); 
    } 
} 

使用法:、SimpleInjectorAutofacNinjectStructureMap

interface IDependency 
{ 
    string GetName(); 
} 

class ConcreteDependency : IDependency 
{ 
    public string GetName() 
    { 
     return "Concrete Dependency"; 
    } 
} 

class ConstructorExample 
{ 
    readonly IDependency dependency; 

    public ConstructorExample(IDependency dependency) 
    { 
     this.dependency = dependency; 
    } 

    public string GetString() 
    { 
     return "Consumer of " + dependency.GetName(); 
    } 
} 

class SetterExample 
{ 
    public IDependency Dependency { get; set; } 

    public string GetString() 
    { 
     return "Consumer of " + Dependency.GetName(); 
    } 
} 

[TestMethod] 
public void MyTestMethod() 
{ 
    var container = new Container(); 
    container.Register<IDependency>(c => new ConcreteDependency()); 
    container.Register(c => new ConstructorExample(c.Resolve<IDependency>())); 
    container.Register(c => new SetterExample() { Dependency = c.Resolve<IDependency>() }); 

    var constructor = container.Resolve<ConstructorExample>(); 
    Assert.AreEqual("Consumer of Concrete Dependency", constructor.GetString()); 

    var setter = container.Resolve<SetterExample>(); 
    Assert.AreEqual("Consumer of Concrete Dependency", setter.GetString()); 
} 

あなたは、より高度な取得したい場合は、私はこれらのいずれかのソースを取得して推薦します。

+0

ありがとうございました。私はインターフェイスとセッターのジェネリックスを書く方法を理解しようとしていて、最後の3日間は苦労していました。 –

関連する問題