Domanda

Sto usando Microsoft Unità per l'iniezione di dipendenza e voglio fare qualcosa di simile a questo:

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 e RepositoryB entrambi hanno un costruttore che prende un IDataContext parametro, e voglio Unità per inizializzare il repository con il contesto che lo passo.Anche notare che IDataContext non è registrato con l'Unità (non voglio 3 istanze di IDataContext).

È stato utile?

Soluzione

Ad oggi hanno aggiunto questa funzionalità:

E 'nella sua ultima goccia qui:

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

Discussione su di esso qui:

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

Esempio:

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

Altri suggerimenti

< 2 cents>

Cosa succede se in un secondo momento decidere di utilizzare un altro servizio che richiede più o meno che proprio contesto?

Il problema con i parametri del costruttore e Cio è che i parametri sono, in definitiva, legata al tipo di calcestruzzo utilizzato, invece di essere parte del contratto che l'interfaccia del servizio definisce.

Il mio suggerimento è che si sia risolto il contesto, e credo che l'Unità deve avere un modo per evitare la costruzione di 3 istanze di esso, o si dovrebbe prendere in considerazione un servizio di fabbrica che è un modo per costruire l'oggetto.

Per esempio, se in un secondo momento decidere di costruire un repository che non si basa su un database di tipo tradizionale, ma invece di utilizzare un file XML per produrre dummy-i dati per il test?Come si va su di alimentazione il contenuto XML per costruttore?

Cio è basato intorno disaccoppiamento codice, legando il tipo e la semantica degli argomenti per i calcestruzzi, davvero non hanno fatto il disaccoppiamento correttamente, c'è ancora una dipendenza.

"Questo codice può parlare di qualsiasi tipo di repository forse, come lungo come si implementa questa interfaccia....Oh, e utilizza un contesto di dati".

Ora, so che altri IoC container dispone di supporto per questo, e l'ho avuto nella mia prima versione del mio bene, ma a mio parere, non appartiene con la risoluzione passo.

< /2 cents>

Grazie ragazzi ... il mio è simile al post di "Exist". Vedi sotto:

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

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

È possibile utilizzare InjectionConstructor / InjectionProperty / InjectionMethod a seconda della architettura di iniezione all'interno del ResolvedParameter ( "nome") per ottenere un'istanza di un oggetto pre-registrate nel contenitore.

Nel tuo caso l'oggetto deve essere registrato con un nome, e per lo stesso insance è necessario ContainerControlledLifeTimeManager () come 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 risposta molto breve è: no. Unità attualmente non ha modo di passare parametri al costruttore che non sono costanti o iniettato, che ho potuto trovare. IMHO questa è la cosa più grande che manca, ma penso che è di progettazione, piuttosto che per omissione.

Come osserva Jeff Fritz, in teoria è possibile creare un gestore di vita personalizzato che sa quale istanza di contesto per iniettare in varie tipologie, ma questo è un livello di hard-codifica che sembra ovviare lo scopo di utilizzare l'unità o DI nel primo posto.

Si potrebbe fare un piccolo passo indietro dalla piena DI ed effettuare le implementazioni repository responsabile di stabilire i propri contesti di dati. Il contesto istanza può ancora essere risolta dal contenitore, ma la logica per decidere quale usare avrebbe dovuto andare in attuazione del repository. Non è così puro, certamente, ma sarebbe sbarazzarsi del problema.

Un'altra alternativa è possibile utilizzare (non so davvero se si tratta di una buona pratica o no) è la creazione di due contenitori e registrazione un'istanza per ogni:

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

Spero che questo aiuti anche

NotDan, penso che si può avere risposto alla tua domanda nei commenti a lassevk.

In primo luogo, vorrei utilizzare un LifetimeManager per gestire il ciclo di vita e il numero di istanze di IDataContext che l'unità crea.
http://msdn.microsoft.com/en-us/library/cc440953. aspx

Sembra che l'oggetto ContainerControlledLifetimeManager vi darà la gestione delle istanze di cui avete bisogno. Con questo LifetimeManager in atto, Unità dovrebbe aggiungere la stessa istanza del IDataContext a tutti gli oggetti che richiedono una dipendenza IDataContext.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top