Aiutami a risolvere questa dipendenza circolare?

0

Sarebbe dietro un tag spoiler se potessi ottenere il markdown per funzionare. Siamo spiacenti.

As soon as I typed in "circular dependency", I got a ton of suggested results. Such as:

I've read through those, and others. I still don't know how to solve my problem, thus this question:

Ok, domanda vera.

Il metodo "tipico" di iniezione delle dipendenze per un livello di accesso ai dati è simile a questo:

  1. Crea un'interfaccia per il tuo livello di persistenza all'interno del tuo livello dominio.
  2. I tuoi servizi di dominio accettano tale interfaccia nei loro costruttori.
  3. Assicurati che il tuo livello di persistenza implementa tale interfaccia. Ciò implica che lo strato di persistenza dipende dal livello del dominio e tutto è buono.
  4. Il tuo livello client ha riferimenti al livello dominio e al livello di persistenza.
  5. Il tuo livello client crea un'istanza dell'oggetto di persistenza e lo inietta nei servizi di dominio. Questo in genere viene eseguito con una clausola using .

Ad esempio:

// Simplified...
using (var p = new PersistenceThing ()) {
    var s = new ServiceThing (p);
}

... e se hai più livelli ...

using (var p = new PersistenceThing ()) {
    using (var s1 = new LowerLayerThing (p)) {
        using (var s2 = new HigherLayerThing (s1)) {
            // How deep does the rabbit hole go before you can actually do anything?
        }
    }
}

Ho un'esigenza valida per spostare la creazione di questi oggetti di servizio nelle fabbriche. (I motivi sono lunghi, che comportano la separazione in livelli separati). Questo cambia un po 'il layout del mio progetto.

Andando dall'alto verso il basso:

  • Ho un progetto client.
  • Di seguito, ho un progetto "interfaccia di livello superiore" che contiene il contratto di servizio per il livello e la fabbrica per il livello. Il progetto client deve solo fare riferimento a questo progetto "upper layer interface".
  • Successivamente, ho un livello di "livello superiore di implementazione". Questo livello fa riferimento al progetto "upper layer interface" e al progetto "lower layer interface".
  • Poi c'è un progetto "interfaccia di livello inferiore" contenente il contratto di servizio e la fabbrica. Non fa riferimento a nulla.
  • Quindi un livello di "implementazione di livello inferiore". Fa riferimento al progetto "interfaccia di livello inferiore" e ... e ...

E poi arrivo al livello di persistenza e tutto si spezza.

Ho bisogno di una fabbrica per gestire l'istanza del mio livello di persistenza. Il livello di servizio inferiore deve avere o fare riferimento all'interfaccia di persistenza perché è ciò contro cui sta lavorando. La factory deve avere o fare riferimento alla stessa interfaccia in modo che possa esporre la firma del metodo corretta. Abbastanza facile: il progetto "interfaccia di persistenza" fa riferimento al progetto "lower service". Ma il progetto "servizio inferiore" deve avere accesso alla fabbrica in modo che possa ottenere un'istanza del livello di persistenza.

Il mio primo pensiero è stato spostare l'interfaccia nel progetto "persistence interface", ma ha ancora bisogno di un riferimento al progetto "lower service" perché fa riferimento a tutti i tipi di oggetti di dominio. Il mio secondo pensiero è stato spostare la fabbrica nel progetto "servizio inferiore", ma ha bisogno di riferimenti al livello "implementazione persistenza" in modo che abbia qualcosa da istanziare. Ma il livello di "implementazione della persistenza" avrebbe ancora bisogno di un riferimento al livello "dominio inferiore" in modo che io possa implementare l'interfaccia.

    
posta J Fenter 10.08.2016 - 23:09
fonte

1 risposta

2

Non è così che funziona l'architettura a strati (o a livelli). Nello specifico: ogni livello ha solo la conoscenza degli strati direttamente sotto di esso e di tutti gli oggetti condivisi richiesti. Che contraddice gli articoli 4 e 5 nella tua lista di come funziona l'iniezione di dipendenza tipica. Ecco perché hai un problema di dipendenza circolare.

In un sistema a tre strati costituito da livelli client, dominio e persistenza:  1. I livelli client "conoscono" il livello del dominio tramite interfacce e oggetti dati condivisi  2. Il livello del dominio "conosce" le interfacce del livello client (perché le implementa) e gli oggetti dati condivisi richiesti dal client  3. Il livello del dominio "conosce" anche le interfacce del livello di persistenza e gli oggetti dati condivisi di persistenza.  4. Il livello di persistenza "conosce" le interfacce del livello di persistenza (perché le implementa) e gli oggetti dati condivisi di persistenza

Quindi finirai con cinque progetti. Un progetto client, un progetto di dominio, un progetto di persistenza, un progetto a cui fa riferimento il client e il dominio e un progetto a cui fanno riferimento dominio e persistenza. Se si dispone di un oggetto dati comune a cui si desidera fare riferimento in tutti i livelli, questo verrà inserito in un altro progetto.

Supponendo che si tratti di un'applicazione desktop, si avrà un progetto padre aggiuntivo che fa riferimento a tutto ma è solo lì per avviare l'app. In quel progetto puoi usare qualcosa come Unity per fare la tua iniezione vera e propria.

    
risposta data 11.08.2016 - 02:34
fonte

Leggi altre domande sui tag