Question

J'utilise l'unité de Microsoft pour l'injection de dépendance et je veux 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 RepositoryB les deux ont un constructeur qui prend un paramètre IDataContext, et je veux l'unité pour initialiser le référentiel avec le contexte que je transmets. A noter également que IDataContext n'est pas enregistré avec l'unité (je ne veux pas 3 cas de IDataContext).

Était-ce utile?

La solution

A ce jour, ils ont ajouté cette fonctionnalité:

Il est dans la dernière goutte ici:

http://unity.codeplex.com/SourceControl/changeset/view/33899

Discussion sur le sujet ici:

http://unity.codeplex.com/Thread/View.aspx? ThreadId = 66434

Exemple:

container.Resolve<IFoo>(new ParameterOverrides<Foo> { { "name", "bar" }, { "address", 42 } });"

Autres conseils

<2 cents>

Que faire si vous plus tard décidez d'utiliser un autre service qui nécessite plus ou moins que le contexte?

Le problème avec les paramètres du constructeur et la COI est que les paramètres sont finalement liés au type de béton utilisé, au lieu d'être une partie du contrat que l'interface de service définit.

Ma suggestion serait que vous soit résoudre le contexte aussi bien, et je crois que l'unité devrait avoir un moyen pour vous d'éviter la construction de 3 cas de celui-ci, ou vous devriez envisager un service d'usine qui a une façon pour vous de construire la objet.

Par exemple, si vous décidez par la suite de construire un référentiel qui ne repose pas sur une base de données traditionnelle du tout, mais au lieu d'utiliser un fichier XML pour produire des données fictives pour le test? Comment feriez-vous de nourrir le contenu XML à ce constructeur?

IoC est basé sur le code de découplage, en liant dans le type et la sémantique des arguments aux types concrets, vous avez vraiment pas fait correctement le découplage, il y a encore une dépendance.

« Ce code peut parler à tout type de dépôt peut-être, aussi longtemps qu'il implémente cette interface .... Oh, et utilise un contexte de données ».

Maintenant, je sais que d'autres conteneurs IoC supportent cela, et je l'avais dans ma première version de mon propre bien, mais à mon avis, il ne fait pas partie de l'étape de résolution.

Merci les gars ... Le mien est similaire au poste par « Exister ». Voir ci-dessous:

        IUnityContainer container = new UnityContainer();
        container.LoadConfiguration();

        _activeDirectoryService = container.Resolve<IActiveDirectoryService>(new ResolverOverride[]
        {
            new ParameterOverride("activeDirectoryServer", "xyz.adserver.com")
        });

Vous pouvez utiliser InjectionConstructor / InjectionProperty / InjectionMethod selon votre architecture d'injection dans le ResolvedParameter ( « nom ») pour obtenir une instance d'un objet pré-enregistré dans le récipient.

Dans votre cas, cet objet doit être enregistré avec un nom, et pour la même insance vous avez besoin ContainerControlledLifeTimeManager () comme LifeTimeManager.

_unityContainer.RegisterType<IDataContext,DataContextA>("DataContextA", new ContainerControlledLifeTimeManager());
_unityContainer.RegisterType<IDataContext,DataContextB>("DataContextB");

  var repositoryA = _unityContainer.Resolve<IRepositoryA>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextA")));

  var repositoryB = _unityContainer.Resolve<IRepositoryB>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextA")));

  var repositoryA2 = _unityContainer.Resolve<IRepositoryA>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextB")));

La réponse très courte est: non. L'unité n'a actuellement aucun moyen de passer des paramètres dans le constructeur qui ne sont pas constantes ou injecté, que j'ai pu trouver. À mon humble avis, c'est la plus grande chose qu'il manque, mais je pense qu'il est par la conception plutôt que par omission.

Comme le fait remarquer Jeff Fritz, vous pourriez en théorie créer un gestionnaire de vie personnalisé qui sait quelle instance contexte d'injecter dans divers types, mais qui est un niveau de codage en dur qui semble éviter le but d'utiliser l'unité ou DI dans le premier endroit.

Vous pouvez prendre un petit pas en arrière de la pleine DI et faire vos mises en œuvre du référentiel responsable de l'établissement de leurs propres contextes de données. Le contexte par exemple peut encore être résolu du conteneur, mais la logique de décider lequel utiliser devrait aller dans la mise en œuvre du référentiel. Ce n'est pas aussi pur, certes, mais il se débarrasser du problème.

Une autre alternative, vous pouvez utiliser (ne sais pas vraiment si elle est une bonne pratique ou non) est la création de deux conteneurs et l'enregistrement d'une instance pour chaque:

IDataContext context = _unityContainer.Resolve<IDataContext>();
_unityContainer.RegisterInstance(context);
var repositoryA = _unityContainer.Resolve<IRepositoryA>(); //Same instance of context
var repositoryB = _unityContainer.Resolve<IRepositoryB>(); //Same instance of context


//declare _unityContainer2
IDataContext context2 = _unityContainer2.Resolve<IDataContext>(); //New instance
_unityContainer2.RegisterInstance(context2);
var repositoryA2 = _unityContainer2.Resolve<IRepositoryA>(context2); //will retrieve the other instance

Espérons que cela aide aussi

NotDan, je pense que vous avez répondu à votre propre question dans les commentaires à lassevk.

D'abord, je voudrais utiliser un LifetimeManager pour gérer le cycle de vie et le nombre de cas de IDataContext que l'unité crée.
http://msdn.microsoft.com/en-us/library/cc440953. aspx

On dirait que l'objet ContainerControlledLifetimeManager vous donnera la gestion de l'instance que vous avez besoin. Avec cette LifetimeManager en place, l'unité doit ajouter la même instance de la IDataContext à tous les objets qui nécessitent une dépendance IDataContext.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top