siamo abbastanza nuovi in DI e stiamo effettuando il refactoring della nostra applicazione per utilizzare Prism / Unity. Siamo quasi arrivati ma siamo rimasti bloccati su una dipendenza circolare. Ho letto molto, ci sono un sacco di domande simili ma sono in dubbio su quale sarebbe una soluzione 'corretta' nella nostra situazione.
L'applicazione è simile ad alcuni IDE. Abbiamo un progetto di esplorazione, ricerca, documenti, ... I documenti sono in realtà visualizzazioni ad albero con nodi di INodeViewModel. Nota che gli esempi di codice sono versioni ridotte al minimo del codice reale.
Abbiamo un IDockingService
che gestisce gli strumenti e gli elementi del documento.
public interface IDockingService
{
INodeViewModelNavigationService NodeViewModelNavigationService { get; }
ExplorerViewModel ExplorerViewModel { get; }
SearchViewModel SearchViewModel { get; }
ReadOnlyCollection<ToolItemViewModel> ToolItemViewModels { get; }
ReadOnlyCollection<DocumentItemViewModel> DocumentItemViewModels { get; }
}
E abbiamo un ISpecificationViewModelService
che gestisce tutti gli INodeViewModels e ha la connessione con il modello.
public interface ISpecificationViewModelService
{
INodeViewModel RootX { get; }
INodeViewModel RootY { get; }
INodeViewModel RootZ { get; }
}
Abbiamo due requisiti in conflitto.
- Quando un nuovo nodo viene creato da qualche parte, vogliamo navigare verso di esso. Attualmente passiamo
IDockingService
tramite l'iniezione del costruttore a l'implementazione concretaSpecificationViewModelService
e più avanti in ogni NodeViewModel. - Alcuni strumenti in
DockingService
devono conoscere ilISpecificationViewModelService
. Ad esempio, l'Explorer deve mostrare tutte le radici.
Poiché DockingItemService
crea e gestisce i toolitems come Explorer ha bisogno di ISpecificationViewModelService
. Ma ISpecificationViewModelService
ha bisogno del IDockingService
per essere in grado di navigare verso un nodo. Problemi circolari.
Il nostro primo tentativo non ha avuto questo problema perché abbiamo lasciato che gli elementi dello strumento fossero creati nella radice della composizione ma ciò non sembrava corretto. Istanze non gestite bene insieme.
Da leggere in giro capisco che una fabbrica (o un'altra terza classe) potrebbe aiutare qui. Non vedo ancora. Penso di capire che il problema è che DockingService
ha solo bisogno di SpecificationViewModelService
per creare i toolitems e viceversa. Una fabbrica potrebbe portare via questo problema circolare, ma non sono sicuro che sia una soluzione corretta. Il contenitore può essere usato solo nella radice della composizione ma non dovrebbe fare una facory (che ha bisogno del contenitore?), Quindi nascondere il contenitore e assumere il suo lavoro con un nome diverso?
Quale sarebbe un modo corretto per gestire questo problema?