Frage

Ich bin mit Microsoft Unity für Dependency Injection und ich möchte etwas tun:

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 und beide RepositoryB haben einen Konstruktor, der einen IDataContext Parameter nimmt, und ich möchte Unity das Repository mit dem Kontext initialisieren, dass ich es übergeben. Beachten Sie auch, dass IDataContext nicht mit Unity registriert (Ich möchte nicht, 3 Fälle von IDataContext).

War es hilfreich?

Lösung

Ab heute haben sie diese Funktionalität wurde hinzugefügt:

Es ist in der neuesten Drop hier:

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

Die Diskussion über es hier:

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

Beispiel:

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

Andere Tipps

<2 Cent>

Was ist, wenn Sie später auf einen anderen Dienst zu verwenden, die mehr oder weniger als nur den Zusammenhang?

Das Problem mit Konstruktorparameter und IoC ist, dass die Parameter letztlich auf die konkrete Art gebunden sind, verwendet werden, im Gegensatz Teil des Vertrages ist, dass die Service-Schnittstelle definiert.

Mein Vorschlag wäre, dass Sie entweder den Kontext lösen als auch, und ich glaube, Unity eine Möglichkeit haben, sollten Sie drei Instanzen davon zu vermeiden konstruieren, oder sollten Sie eine Fabrik-Service betrachten, die eine Möglichkeit für Sie, die zu konstruieren hat Objekt.

Zum Beispiel, was passiert, wenn Sie später entscheiden, ein Repository zu erstellen, die auf einer traditionellen Datenbank gar nicht verlassen, sondern stattdessen eine XML-Datei verwenden Dummy-Daten für den Test zu produzieren? Wie würden Sie gehen über den XML-Inhalt in diesem Konstruktor Fütterung?

IoC basiert auf Code Entkopplung von der Art und Semantik der Argumente zu den konkreten Typen binden, Sie haben wirklich nicht die Entkopplung richtig gemacht, es gibt immer noch eine Abhängigkeit.

„Dieser Code kann möglicherweise auf jede Art von Repository sprechen, solange es diese Schnittstelle implementiert .... Oh, und verwendet einen Datenkontext“.

Nun, ich weiß, dass andere IoC Container Unterstützung haben für diesen, und ich hatte es in meiner ersten Version meines eigenen als gut, aber meiner Meinung nach, ist es nicht mit dem Auflösungsschritt gehört.

Danke Jungs ... Mine ist ähnlich den Beitrag von „Exist“. Siehe unten:

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

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

Sie können mit InjectionConstructor / InjectionProperty / InjectionMethod auf Injection Architektur im ResolvedParameter je ( „name“) eine Instanz eines vorregistrierten Objekt in dem Behälter zu erhalten.

In Ihrem Fall das Objekt mit einem Namen registriert werden muß und für die gleiche insance müssen Sie ContainerControlledLifeTimeManager () als 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")));

Die sehr kurze Antwort lautet: nein. Unity hat derzeit keine Möglichkeit, Parameter an den Konstruktor übergeben, die nicht konstant oder injiziert sind, dass ich in der Lage gewesen zu finden. IMHO, dass die größte Sache ist, es fehlt, aber ich denke, es ist konstruktionsbedingt und nicht durch Unterlassung.

Wie Jeff Fritz merkt man in der Theorie eine benutzerdefinierte Lebensdauer Manager erstellen können, die die Context-Instanz zu injizieren, in verschiedene Typen kennt, aber das ist ein Niveau von Hartcodierung, die den Zweck der Verwendung von Unity oder DI in der ersten zu vermeiden scheint Ort.

Sie können einen kleinen Schritt von der vollständigen DI zurück und Repository-Implementierungen für den Aufbau ihrer eigenen Daten Kontexten verantwortlich machen. Der Kontext Instanz kann nach wie vor aus dem Behälter gelöst werden, aber die Logik für die Entscheidung, die man hätte verwenden müssen in die Umsetzung des Endlagers gehen. Es ist nicht so rein, sicher, aber es würde das Problem loszuwerden.

Eine weitere Alternative, die Sie verwenden können (nicht wirklich wissen, ob es eine gute Praxis ist oder nicht) ist die Schaffung von zwei Containern und eine Instanz für jede Registrierung:

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

hoffe, das hilft auch

NotDan, ich glaube, Sie Ihre eigene Frage in den Kommentaren beantwortet haben können lassevk.

Als erstes würde ich einen LifetimeManager verwenden, um die Lebensdauer und Anzahl der Instanzen von IDataContext zu verwalten, dass die Einheit schafft.
http://msdn.microsoft.com/en-us/library/cc440953. aspx

Es klingt wie die ContainerControlledLifetimeManager Objekt wird die Instanz-Management, die Sie benötigen. Mit diesem LifetimeManager vorhanden, sollte die Einheit die gleiche Instanz der IDataContext auf alle Objekte hinzufügen, die eine IDataContext Abhängigkeit benötigen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top