Я думаю, що ваше приміщення тут трохи заплутане, ви говорите про введення фабрики, але заводський зразок - це креативний шаблон, метою якого було зробити підмножину того, що робить схема введення залежності, коли рамки DI не переважали. корисна з цієї причини. Однак якщо у вас є рамка DI, вам більше не потрібна фабрика, оскільки рамка DI може виконувати мету, яку фабрика виконала б.
З цього приводу, дозвольте мені пояснити трохи ін'єкцію залежності та як ви її взагалі використовуєте.
Існує безліч способів зробити ін'єкцію залежності, але найпоширенішими є введення конструктора, введення властивостей та прямий DIContainer. Я буду говорити про введення конструктора, оскільки введення властивостей є неправильним підходом більшість часу (правильний підхід у деякий час), і доступ до DIContainer не є кращим, за винятком випадків, коли ви абсолютно не можете зробити жоден з інших підходів.
Інжектор конструкторів - це те, де у вас є інтерфейс для залежності та DIContainer (або фабрика), який знає конкретну реалізацію для цієї залежності, і де б вам не потрібен об'єкт, який залежить від цього інтерфейсу, під час створення ви передаєте реалізацію від заводу до це.
тобто
IDbConnectionProvider connProvider = DIContainer.Get<IDbConnectionProvider>();
IUserRepository userRepo = new UserRepository(connProvider);
User currentUser = userRepo.GetCurrentUser();
Багато рамок DI можуть значно спростити це до того, де ваш DIContainer буде перевіряти конструктор UserRepository на предмет інтерфейсів, для яких він знає конкретні реалізації, і автоматично передасть їх вам; цю техніку часто називають інверсією управління, хоча DI та IoC - це обидва терміни, які сильно змінюються і мають розпливчасті (якщо такі є) відмінності.
Тепер, якщо вам цікаво, як всеохоплюючий код отримує доступ до DIContainer, добре, що ви можете мати статичний клас для доступу до нього, або що є більш підходящим, це те, що більшість фреймворків DI дозволяють вам створити DIContainer, при цьому він насправді просто поводитиметься як обгортка до внутрішнього словника одиночного типу для тих типів, які він знає конкретними для заданих інтерфейсів.
Це означає, що ви можете створити DIContainer в будь-якому місці, де вам захочеться, і ефективно отримати той самий DIContainer, який ви вже налаштували, щоб знати ваші взаємозв'язки між конкретними. Звичайний спосіб приховати DIContainer від частин коду, які не повинні безпосередньо взаємодіяти з ним, - це просто переконатися, що лише необхідні проекти мають посилання на рамку DI.