J'utilise Unity de Microsoft pour l'injection de dépendances et je souhaite faire quelque chose comme ceci:
IDataContext context = _unityContainer.Resolve<IDataContext>();
var repositoryA = _unityContainer.Resolve<IRepositoryA>(context); //Same instance of context
var repositoryB = _unityContainer.Resolve<IRepositoryB>(context); //Same instance of context
IDataContext context2 = _unityContainer.Resolve<IDataContext>(); //New instance
var repositoryA2 = _unityContainer.Resolve<IRepositoryA>(context2);
RepositoryA
et les RepositoryB
deux ont un constructeur qui prend un IDataContext
paramètre, et je veux qu'Unity initialise le référentiel avec le contexte que je lui passe. Notez également que ce IDataContext
n'est pas enregistré avec Unity (je ne veux pas 3 instances de IDataContext
).
Foo(string name, int address) { ... }
container.Resolve<IFoo>(new ParameterOverrides { { "name", "bar" }, { "address", 42 } });
<2 cents>
Et si vous décidez plus tard d'utiliser un service différent qui nécessite plus ou moins que le contexte?
Le problème avec les paramètres du constructeur et l'IoC est que les paramètres sont finalement liés au type concret utilisé, au lieu de faire partie du contrat défini par l'interface de service.
Ma suggestion serait que vous résolviez également le contexte, et je pense que Unity devrait avoir un moyen pour vous d'éviter de construire 3 instances de celui-ci, ou vous devriez envisager un service d'usine qui vous permet de construire l'objet.
Par exemple, que se passe-t-il si vous décidez plus tard de construire un référentiel qui ne repose pas du tout sur une base de données traditionnelle, mais qui utilise plutôt un fichier XML pour produire des données factices pour le test? Comment feriez-vous pour transmettre le contenu XML à ce constructeur?
IoC est basé sur le découplage du code, en liant le type et la sémantique des arguments aux types concrets, vous n'avez vraiment pas fait le découplage correctement, il y a toujours une dépendance.
"Ce code peut éventuellement parler à n'importe quel type de référentiel, du moment qu'il implémente cette interface ... Oh, et utilise un contexte de données".
Maintenant, je sais que d'autres conteneurs IoC prennent en charge cela, et je l'avais également dans ma première version, mais à mon avis, cela n'appartient pas à l'étape de résolution.
</ 2 cents>
la source
Merci les gars ... le mien est similaire au post de "Exist". Voir ci-dessous:
la source
Vous pouvez utiliser InjectionConstructor / InjectionProperty / InjectionMethod en fonction de votre architecture d'injection dans ResolvedParameter <T> ("name") pour obtenir une instance d'un objet pré-enregistré dans le conteneur.
Dans votre cas, cet objet doit être enregistré avec un nom, et pour la même insance, vous avez besoin de ContainerControlledLifeTimeManager () comme LifeTimeManager.
la source
Resolve
prend une collection deResolverOverride
, etInjectionConstructor
n'est pas un fichierResolverOverride
.La réponse très courte est: non. Unity n'a actuellement aucun moyen de passer des paramètres dans le constructeur qui ne sont pas constants ou injectés, que j'ai pu trouver. À mon humble avis, c'est la chose la plus importante qui manque, mais je pense que c'est par conception plutôt que par omission.
Comme le note Jeff Fritz, vous pouvez en théorie créer un gestionnaire de durée de vie personnalisé qui sait quelle instance de contexte injecter dans différents types, mais c'est un niveau de codage en dur qui semble obvier à l'objectif d'utiliser Unity ou DI en premier lieu.
Vous pouvez prendre du recul par rapport à la DI complète et confier à vos implémentations de référentiel la responsabilité d'établir leurs propres contextes de données. L' instance de contexte peut toujours être résolue à partir du conteneur, mais la logique pour décider lequel utiliser devrait aller dans l'implémentation du référentiel. Ce n'est certainement pas aussi pur, mais cela éliminerait le problème.
la source
Une autre alternative que vous pourriez utiliser (je ne sais pas vraiment si c'est une bonne pratique ou non) consiste à créer deux conteneurs et à enregistrer une instance pour chacun:
j'espère que cela aide aussi
la source
NotDan, je pense que vous avez peut-être répondu à votre propre question dans des commentaires à lassevk.
Tout d'abord, j'utiliserais un LifetimeManager pour gérer le cycle de vie et le nombre d'instances d'IDataContext que Unity crée.
http://msdn.microsoft.com/en-us/library/cc440953.aspx
Il semble que l'
ContainerControlledLifetimeManager
objet vous donnera la gestion d'instance dont vous avez besoin. Avec ce LifetimeManager en place, Unity doit ajouter la même instance de IDataContext à tous les objets qui nécessitent une dépendance IDataContext.la source