2009-11-06 10 views
9

To jest to, co chcę od DI kontenera:Które kontenera DI zaspokoi tę

public class Class 
{ 
    public Class(IDependency dependency, string data) { } 
} 

var obj = di.Resolve<Class>(() => new Class(null, "test")); 

Ciekawostki:

  1. można rozwiązać zarówno zależność i danych w konstruktorze.
  2. Potrafi używać składni bezpiecznej do przesyłania parametrów konstruktora (dokładna składnia może być różna). Tak, mogę to zrobić samodzielnie, pobierając argumenty konstruktora z (Expression.Body jako NewExpression) - ale potrzebuję sposobu na wykrycie, które argumenty są zarejestrowane w kontenerze.

Innym ważnym wymaganiem jest to, że chciałbym, aby moje komponenty były automatycznie pobierane, tj. Nie chcę rejestrować klasy - chcę, aby IoC ją odebrał, ponieważ wie, jak rozwiązać problem niezależności.

Ponadto czasami może być przydatne wprowadzanie właściwości, ale jest to opcjonalne.

Pytanie dotyczy tak naprawdę kombinacji cech - posiadania wszystkich typów - bezpieczeństwa, parametrów, automatycznego odbioru ... Łatwo jest sprawdzić jedną funkcję, ale ich połączenie nie jest łatwe do zweryfikowania chyba że ktoś zna określony pojemnik i zna jego cechy. Tak więc pytanie.

+0

Nie sądzę, że istnieje kontener obsługujący tego rodzaju składnię. Ale wiele (prawie wszystkie) kontenerów obsługuje jawne parametry kontenera, i prawdopodobnie z czystszą składnią. –

+0

"Prawdopodobnie" nie jest odpowiedzią ... o ile wiem, mogę przekazać obiektową [] tablicę parametrów, ale oczywiście nie jest to bezpieczny typ ... Mogę zmienić kolejność parametrów i nie będę o tym wiedział aż do czasu wykonania . – queen3

+0

Przez środek czyszczący rozumiałem, że nie musisz wyraźnie używać ctor w swoim kodzie, tak jak robisz to powyżej. Zamiast tego, co napisałeś, dlaczego nie: 'var obj = new Class (di.Resolve ()," test ");'? –

Odpowiedz

27

Myślę, że lepiej byłoby, gdybyś zdefiniował abstrakcyjną fabrykę, która może stworzyć twoją klasę.

public interface IFactory 
{ 
    MyClass Create(string data); 
} 

Następnie można utworzyć realizację IFactory takiego:

public class MyFactory : IFactory 
{ 
    private IDependency dependency; 

    public MyFactory(IDependency dependency) 
    { 
     if (dependency == null) 
     { 
      throw new ArgumentNullException("dependency"); 
     } 

     this.dependency = dependency; 
    } 

    #region IFactory Members 

    public MyClass Create(string data) 
    { 
     return new MyClass(this.dependency, data); 
    } 

    #endregion 
} 

W kontenerze, należy zarejestrować się zarówno MyFactory i realizację IDependency.

Teraz można użyć kontenera rozwiązać fabryce, fabryce, aby uzyskać klasę:

var mc = container.Resolve<IFactory>().Create(data); 

Takie podejście jest całkowicie bezpieczny i wpisać ładnie oddziela zależności od danych aplikacji run-time.

+0

Dokładnie! ...................... –

+7

Punkty premiowe za wywołanie go za pomocą nazwy Streszczenie Fabryka, ale za pomocą interfejsu.Widziałem wielu ludzi, którzy słysząc * Abstract * Factory przechodzą od razu do abstrakcyjnej klasy bazowej. –

+2

Tak, wiem o tym, ale w moim przypadku waham się, ponieważ w prostych przypadkach przesadne jest duplikowanie konstruktora z interfejsem, fabryką, konstruktorem fabryki, metodą Create itp. Chociaż jest dobre dla złożonych przypadków, to jest też "wybuch DI" dla prostych rzeczy. myśleć. I pozostaje pytanie o automatyczny pojemnik DI rejestracji. – queen3

Powiązane problemy