Je pense que votre prémisse est un peu confuse ici, vous parlez d'injecter une usine, mais le modèle d'usine est un modèle de création dont le but était de faire un sous-ensemble de ce que fait un cadre d'injection de dépendance, lorsque les cadres DI n'étaient pas répandus, ce modèle était utile pour cette raison. Cependant, si vous avez un cadre DI, vous n'avez plus vraiment besoin d'une usine car le cadre DI peut remplir le but que l'usine aurait atteint.
Cela dit, permettez-moi d'expliquer un peu l'injection de dépendance et comment vous l'utiliseriez généralement.
Il existe différentes manières de faire l'injection de dépendances, mais les plus courantes sont l'injection de constructeur, l'injection de propriété et le DIContainer direct. Je vais parler de l'injection de constructeur car l'injection de propriété est la mauvaise approche la plupart du temps (la bonne approche parfois) et l'accès DIContainer n'est pas préférable, sauf lorsque vous ne pouvez absolument pas faire l'une des autres approches.
L'injection de constructeur est l'endroit où vous avez l'interface pour une dépendance et un DIContainer (ou fabrique) qui connaît l'implémentation concrète pour cette dépendance, et où que vous ayez besoin d'un objet qui dépend de cette interface, au moment de la construction, vous remettez l'implémentation de l'usine à il.
c'est à dire
IDbConnectionProvider connProvider = DIContainer.Get<IDbConnectionProvider>();
IUserRepository userRepo = new UserRepository(connProvider);
User currentUser = userRepo.GetCurrentUser();
De nombreux frameworks DI peuvent simplifier cela de manière significative à l'endroit où votre DIContainer inspectera le constructeur de UserRepository pour les interfaces pour lesquelles il connaît des implémentations concrètes, et leur remettra automatiquement celles-ci pour vous; cette technique est souvent appelée inversion de contrôle, bien que DI et IoC soient tous deux des termes qui s'échangent beaucoup et ont des différences vagues (le cas échéant).
Maintenant, si vous vous demandez comment le code global accède au DIContainer, vous pouvez avoir une classe statique pour y accéder ou ce qui est plus approprié est que la plupart des frameworks DI vous permettent de créer un DIContainer, dans lequel il se comportera comme un wrapper à un dictionnaire singleton interne pour les types qu'il sait être concrets pour des interfaces données.
Cela signifie que vous pouvez renouveler le DIContainer où vous voulez dans le code et obtenir effectivement le même DIContainer que vous aviez déjà configuré pour connaître vos relations interface-à-béton. Le moyen habituel de cacher le DIContainer des parties du code qui ne devraient pas interagir directement avec lui est simplement de s'assurer que le ou les projets nécessaires ont une référence au framework DI.