2011-12-07 11 views
5

Arkaplan

üzerine yardıma ihtiyacı ve nasıl kullanılacağını, ben her üç IOC tekniklerinin bir örnek oluşturmak istiyorum IOC benim anlayış iyileştirmeye yardımcı olmak ve üçüncü parti bir çerçeve kullanmak zorunda kalmadan Arabirim enjeksiyon. Temel bir kurucu enjeksiyon örneğim var, ama setter ve arayüz enjeksiyonu ile mücadele ediyorum.Özel IOC konteyner 2/3 türleri

My Soru

nasıl yere kadar yazma arayüzünü ve ayarlayıcı enjeksiyon mücadele yaklaşımı ki?

İşte benim düşüncelerim, doğru yolda olduğumda bana haber ver.

Arayüz enjeksiyon: çözümlenmiş nesneler aracılığıyla

  1. Döngü uygulanmasına bir arabirim ilişkilendirmek için interfaceDependencyMap çeşit tanımlama
  2. interfaceDependencyMap
  3. uygulanan hangi arayüzleri görmek için kontrol, yapıcı enjeksiyon kullanarak örneği.
  4. yapıcı enjeksiyonu ile başlatıldı nesneye uygun özelliği atama interfaceDependencyMap
  5. kullanarak uygulama çözmek
belirleyici enjeksiyon

: çözüldü nesneler aracılığıyla

  1. Döngü
  2. bazı tanımlama yapıcı enjeksiyon kullanarak örneği setterInjectionMap
  3. Beklenen parametreyi çözümleme MethodInfo
  4. Çağrısı çözüme parametre nesnesi İşte

geçen ayarlayıcı yöntem yapıcı eşleştirmeleri kullanılarak Ben yapıcı enjeksiyon

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

Ve soru nedir? – svick

+0

Bunu yeniden açmamın bir yolu var mı? –

+0

@EricRomanowski: Sorunun neden kapatıldığına dair aşağıdaki nedenleri inceleyin; Sorunuzdaki bu nedenleri ele alabilirseniz, başkaları, SO ile ilgili soruların standartlarını karşıladığını düşündüklerini varsayarak tekrar açılmasını oylayabilirler. – casperOne

cevap

3

için bugüne kadar ne var sen aradığınızı bu tür mı ?

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 
     }); 
    } 
} 

Kullanımı:

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()); 
} 

Daha gelişmiş almak istiyorsanız, bunlardan herhangi kaynağını elde öneriyoruz: SimpleInjector, Autofac, Ninject, StructureMap.

+0

Çok teşekkür ederim. Son üç gün boyunca, arayüz ve ayarlayıcı için jeneriklerin nasıl yazılacağını anlamaya çalışıyordum (uygun bir terminoloji olup olmadığından emin değilim). –