Wydaje mi się, że twoja przesłanka jest tu trochę zagmatwana, mówisz o wstrzykiwaniu fabryki, ale wzorzec fabryczny to wzorzec kreacyjny, którego celem było zrobienie podzbioru tego, co robi struktura wstrzykiwania zależności, gdy szkielety DI nie były rozpowszechnione. przydatne z tego powodu. Jeśli jednak masz środowisko DI, tak naprawdę nie potrzebujesz już fabryki, ponieważ środowisko DI może spełnić cel, który fabryka spełniłaby.
To powiedziawszy, pozwól mi wyjaśnić trochę o wstrzykiwaniu zależności i jak ogólnie byś go użył.
Istnieje wiele sposobów wstrzykiwania zależności, ale najczęstsze to wstrzykiwanie konstruktora, wstrzykiwanie właściwości i bezpośredni DIContainer. Będę mówił o wstrzykiwaniu konstruktora, ponieważ wstrzykiwanie własności jest przez większość czasu niewłaściwym podejściem (właściwe podejście czasami), a dostęp do DIContainer nie jest preferowany, z wyjątkiem sytuacji, gdy absolutnie nie możesz wykonać żadnego z innych podejść.
Wtrysk konstruktora jest miejscem, w którym masz interfejs zależności i DIContainer (lub fabrykę), który zna konkretną implementację tej zależności, i gdziekolwiek potrzebujesz obiektu zależnego od tego interfejsu, w czasie budowy przekazujesz implementację z fabryki do to.
to znaczy
IDbConnectionProvider connProvider = DIContainer.Get<IDbConnectionProvider>();
IUserRepository userRepo = new UserRepository(connProvider);
User currentUser = userRepo.GetCurrentUser();
Wiele frameworków DI może znacznie to uprościć do tego, gdzie DIContainer sprawdzi konstruktora UserRepository pod kątem interfejsów, dla których zna konkretne implementacje, i automatycznie przekaże je za Ciebie; technika ta często nazywana jest Inwersją Kontroli, chociaż zarówno DI, jak i IoC są terminami, które często się wymieniają i mają niejasne (jeśli w ogóle) różnice.
Teraz, gdy zastanawiasz się, w jaki sposób nadrzędny kod uzyskuje dostęp do DIContainer, możesz mieć klasę statyczną do uzyskania dostępu lub bardziej odpowiednie jest to, że większość frameworków DI pozwala na nowe utworzenie DIContainer, przy czym tak naprawdę będzie on zachowywał się jak opakowanie do wewnętrznego słownika singletonów dla typów, o których wiadomo, że są konkretne dla danych interfejsów.
Oznacza to, że możesz odświeżyć DIContainer w dowolnym miejscu w kodzie i skutecznie uzyskać ten sam DIContainer, który już skonfigurowałeś, aby znać swoje relacje między interfejsem. Zwykłym sposobem ukrywania DIContainer przed częściami kodu, które nie powinny bezpośrednio z nim oddziaływać, jest po prostu upewnienie się, że tylko niezbędne projekty mają odniesienie do frameworku DI.