DI: una dipendenza stabile può avere una dipendenza volatile?

4

Recentemente ho letto con Iniezione delle dipendenze in .NET di Mark Seemann e ho tentato di applicare alcune delle cose che ho imparato in un nuovo progetto su cui sto lavorando, e io m stumped su un particolare scenario cercando di determinare quali dipendenze dovrei e non dovrei iniettare. Ho letto molte altre domande su SO e altrove che discutono scenari simili, ma in modo indiretto, e penso di aver ristretto la domanda concettuale sottostante a ciò che è nel titolo:

Una dipendenza stabile può avere una dipendenza volatile? In altre parole: se una dipendenza stabile ha una dipendenza volatile, la dipendenza stabile è davvero stabile?

Un rapido esempio:

public class MyClass
{
    private IVolatileDependency1 _one;
    private StableDependency _stable;

    public MyClass(IVolatileDependency1 one, IVolatileDependency2 two)
    {
        _one = one;
        _stable = new StableDependency(two)
    }
}

public class StableDependency
{
    private IVolatileDependency2 _two;

    public StableDependency(IVolatileDependency2 two)
    {
        _two = two;
    }
}

In questa situazione, MyClass ha una dipendenza stabile che ho scelto di non iniettare, ma invece di creare un'istanza interna e di tenere la composizione. Tuttavia, quella dipendenza stabile ha una dipendenza volatile, che sto iniettando in MyClass e passando al costruttore di StableDependency .

Per qualche ragione, questo mi odora un po '. È abbastanza semplice in un esempio così semplice, ma posso vedere le cose sfuggire rapidamente in una situazione più complicata del mondo reale.

StableDependency è veramente stabile, o dovrei compilarlo / risolverlo prima di costruire MyClass e iniettarlo da lì? Davvero non prevedo che StableDependency cambi o venga sostituito da un'altra implementazione, ma d'altra parte la pratica di passare le dipendenze attraverso le classi genitore ai loro figli (genitore / figlio nel senso della composizione) sembra esporre i dettagli del figli attraverso il genitore, che sarebbe una violazione della legge di Demetra.

EDIT: Modificato VolatileDependency1 e VolatileDependency2 alle interfacce per chiarire che sono intesi per essere soddisfatti da più possibili implementazioni (compatibile con LSP).

EDIT 2: Pensandoci ancora e leggendo la risposta di KeithS e il commento di default.kramer di seguito, fammi capire che forse non avrei dovuto chiamare StableDependency come ho fatto io, perché non pensare che sia una dipendenza in primo luogo. Non è qualcosa che mi aspetto di avere più implementazioni per; è semplicemente un dettaglio di implementazione che MyClass usa la composizione per contenere un StableDependency , quindi la conoscenza di MyClass su come costruire un StableDependency non è un problema che non penso. La grande domanda è, StableDependency fa ha una dipendenza su IVolatileDependency2 , quindi come faccio ad iniettare quella dipendenza? Ho ragione che a tutti gli effetti MyClass ha una dipendenza su IVolatileDependency2 , e il fatto che passi solo la dipendenza fino a StableDependency è un dettaglio di implementazione non correlato a DI?

    
posta mjl5007 13.08.2012 - 22:52
fonte

1 risposta

7

Se StableDependency può accettare qualsiasi implementazione di VolatileDependency2 senza conoscere la differenza tra due di essi (Principio di sostituzione di Liskov), e non è necessario essere in grado di cambiare StableDependency , allora il tuo snippet è perfettamente multa.

Ora, i puristi di DI potrebbero dire che non dovrebbero esserci dipendenze "stabili". Se una classe A dipende da un'altra classe B, c'è sempre la possibilità che B debba essere sostituita con una C: B e quindi si vorrà la flessibilità per iniettare B in modo da non dover ricompilare A per fare questo cambiamento. Nel tuo caso, dichiarando StableDependency , stai affermando che non avrai mai bisogno di un BetterStableDependency . Giusto o sbagliato, chi lo sa; se hai ragione, l'implementazione non cambia mai, ma se ti sbagli, l'implementazione strettamente accoppiata richiede cambiamenti in più punti.

Quando si utilizza un framework IoC per automatizzare il DI, di solito si registra ogni dipendenza con l'IoC, non importa quanto sia probabile che cambi; ce l'hai, perché non usarlo? Quindi, andrei avanti e registrerei StableDependency con il contenitore IoC come IMaybeStableDependency.

    
risposta data 14.08.2012 - 02:10
fonte

Leggi altre domande sui tag