Domanda Cos'è l'iniezione di dipendenza?


Sono già state pubblicate diverse domande con domande specifiche iniezione di dipendenza, come quando usarlo e quali strutture ci sono per esso. Però,

Qual è l'iniezione di dipendenza e quando / perché dovrebbe o non dovrebbe essere utilizzata?


2626
2017-09-25 00:28


origine


risposte:


Fondamentalmente, invece di fare in modo che gli oggetti creino una dipendenza o chiedano a un oggetto factory di crearne uno, passano esternamente le dipendenze necessarie all'oggetto e lo rendi il problema di qualcun altro. Questo "qualcuno" è o un oggetto più in alto sul grafico delle dipendenze, o un injector delle dipendenze (framework) che costruisce il grafico delle dipendenze. Una dipendenza mentre la sto usando qui è qualsiasi altro oggetto a cui l'oggetto corrente deve avere un riferimento.

Uno dei principali vantaggi dell'iniezione di dipendenza è che può rendere più semplici i test. Supponiamo di avere un oggetto che nel suo costruttore fa qualcosa del tipo:

public SomeClass() {
    myObject = Factory.getObject();
}

Questo può essere problematico quando tutto ciò che si vuole fare è eseguire alcuni test unitari su SomeClass, specialmente se myObject è qualcosa che ha un accesso complesso al disco o alla rete. Quindi ora stai cercando di deridere myObject ma in qualche modo intercettando la chiamata factory. Difficile. Invece, passare l'oggetto come argomento al costruttore. Ora hai spostato il problema altrove, ma il test può diventare molto più semplice. Basta fare un dummy myObject e farlo passare. Il costruttore ora assomiglia un po 'a:

public SomeClass (MyClass myObject) {
    this.myObject = myObject;
}

Questo è uno stile di iniezione delle dipendenze, tramite il costruttore. Sono possibili diversi meccanismi.

  • Come notato nei commenti, un'alternativa comune è definire un costruttore del nulla-fare e far sì che le dipendenze vengano iniettate tramite i setter di proprietà (h / t @MikeVella).
  • Martin Fowler documenta una terza alternativa (h / t @MarcDix), in cui le classi implementano esplicitamente un'interfaccia per le dipendenze che desiderano iniettare.

Quando non si utilizza l'iniezione di dipendenza (come nelle classi che fanno troppo lavoro nei loro costruttori ecc.), Tende a diventare molto più difficile isolare i componenti nei test unitari.

Nel 2013, quando scrissi questa risposta, questo era uno dei temi principali su Google Testing Blog. Questo rimane il più grande vantaggio per me, poiché potresti non aver sempre bisogno della flessibilità extra nel tuo progetto di run-time (ad esempio, per localizzatore di servizi o modelli simili), ma spesso devi essere in grado di isolare le tue classi durante i test.


1633
2017-09-25 00:49



La migliore definizione che ho trovato finora è uno di James Shore:

"Iniezione delle dipendenze" è un valore di 25 dollari   termine per un concetto di 5 centesimi. [...]   Iniezione di dipendenza significa dare un   oggetto le sue variabili di istanza. [...].

C'è un articolo di Martin Fowler potrebbe rivelarsi utile anche

L'iniezione di dipendenza fornisce fondamentalmente gli oggetti di cui un oggetto ha bisogno (le sue dipendenze) invece di costruirli da sé. È una tecnica molto utile per i test, poiché consente alle dipendenze di essere derise o eliminate.

Le dipendenze possono essere iniettate in oggetti con molti mezzi (come iniezione del costruttore o iniezione setter). Si può persino usare strutture specializzate per l'iniezione delle dipendenze (ad esempio Spring) per farlo, ma certamente non sono necessarie. Non hai bisogno di questi quadri per avere un'iniezione di dipendenza. Istanziare e passare oggetti (dipendenze) in modo esplicito è un'iniezione altrettanto buona di un'iniezione per quadro.


2058
2017-09-26 16:50



Ho trovato questo divertente esempio in termini di accoppiamento lasco:

Ogni applicazione è composta da molti oggetti che collaborano tra loro per eseguire alcune cose utili. Tradizionalmente ogni oggetto è responsabile per ottenere i propri riferimenti agli oggetti dipendenti (dipendenze) con cui collabora. Questo porta a classi altamente accoppiate e codice difficile da testare.

Ad esempio, prendi in considerazione a Car oggetto.

UN Car dipende da ruote, motore, carburante, batteria, ecc. per funzionare. Tradizionalmente definiamo la marca di tali oggetti dipendenti insieme alla definizione di Car oggetto.

Senza Iniezione di Dipendenza (DI):

class Car{
  private Wheel wh = new NepaliRubberWheel();
  private Battery bt = new ExcideBattery();

  //The rest
}

Qui, il Car oggetto è responsabile della creazione degli oggetti dipendenti.

Cosa succede se vogliamo cambiare il tipo del suo oggetto dipendente - diciamo Wheel - dopo l'iniziale NepaliRubberWheel() forature? Abbiamo bisogno di ricreare l'oggetto Car con la sua nuova dipendenza dire ChineseRubberWheel(), ma solo il Car il produttore può farlo.

Quindi cosa fa il Dependency Injection ci fai per ...?

Quando si utilizza l'iniezione di dipendenza, agli oggetti vengono fornite le loro dipendenze in fase di esecuzione anziché in fase di compilazione (tempo di produzione dell'auto). In modo che ora possiamo cambiare il Wheel quando vogliamo. Qui, il dependency (wheel) può essere iniettato in Car in fase di esecuzione.

Dopo aver usato l'iniezione di dipendenza:

Eccoci qui iniettare il dipendenze (Ruota e batteria) in fase di esecuzione. Da qui il termine: Iniezione di dipendenza. 

class Car{
  private Wheel wh = [Inject an Instance of Wheel (dependency of car) at runtime]
  private Battery bt = [Inject an Instance of Battery (dependency of car) at runtime]
  Car(Wheel wh,Battery bt) {
      this.wh = wh;
      this.bt = bt;
  }
  //Or we can have setters
  void setWheel(Wheel wh) {
      this.wh = wh;
  }
}

Fonte: Comprensione dell'iniezione di dipendenza


507
2018-05-22 04:01



Dipendenza L'iniezione è una pratica in cui gli oggetti sono progettati in modo da ricevere istanze degli oggetti da altri pezzi di codice, invece di costruirli internamente. Ciò significa che qualsiasi oggetto che implementa l'interfaccia richiesta dall'oggetto può essere sostituito senza modificare il codice, il che semplifica il test e migliora il disaccoppiamento.

Ad esempio, considera questi clases:

public class PersonService {
  public void addManager( Person employee, Person newManager ) { ... }
  public void removeManager( Person employee, Person oldManager ) { ... }
  public Group getGroupByManager( Person manager ) { ... }
}

public class GroupMembershipService() {
  public void addPersonToGroup( Person person, Group group ) { ... }
  public void removePersonFromGroup( Person person, Group group ) { ... }
} 

In questo esempio, l'implementazione di PersonService::addManager e PersonService::removeManager avrebbe bisogno di un'istanza di GroupMembershipService per fare il suo lavoro. Senza Iniezione di Dipendenza, il modo tradizionale di fare ciò sarebbe istanziare un nuovo GroupMembershipService nel costruttore di PersonService e usa quell'attributo di istanza in entrambe le funzioni. Tuttavia, se il costruttore di GroupMembershipService ha più cose che richiede, o peggio ancora, ci sono alcuni "setter" di inizializzazione che devono essere chiamati sul GroupMembershipService, il codice cresce piuttosto rapidamente, e il PersonServiceora dipende non solo dal GroupMembershipService ma anche tutto il resto GroupMembershipService dipende da. Inoltre, il collegamento a GroupMembershipService è codificato nel PersonService il che significa che non puoi "inventare" a GroupMembershipService a scopo di test o per utilizzare un modello di strategia in diverse parti dell'applicazione.

Con Iniezione di dipendenza, invece di istanziare il GroupMembershipService dentro il tuo PersonService, o lo avresti passato al PersonService costruttore, oppure aggiungere una proprietà (getter e setter) per impostare un'istanza locale di esso. Questo significa che il tuo PersonService non deve più preoccuparsi di come creare un GroupMembershipService, accetta solo quelli che ha dato e lavora con loro. Questo significa anche tutto ciò che è una sottoclasse di GroupMembershipServiceo implementa il GroupMembershipService l'interfaccia può essere "iniettata" nel PersonService, e il PersonService non ha bisogno di sapere del cambiamento.


233
2017-09-25 06:49



La risposta accettata è buona, ma vorrei aggiungere che DI è molto simile al classico che evita costanti hardcoded nel codice.

Quando si utilizzano alcune costanti come il nome di un database, lo si sposta rapidamente dall'interno del codice in un file di configurazione e si passa una variabile che contiene quel valore nel punto in cui è necessario. La ragione per farlo è che queste costanti di solito cambiano più frequentemente rispetto al resto del codice. Ad esempio se desideri testare il codice in un database di test.

DI è analogo a questo nel mondo della programmazione orientata agli oggetti. I valori lì invece dei costanti costanti sono oggetti interi, ma la ragione per spostare il codice che li crea fuori dal codice di classe è simile - gli oggetti cambiano più frequentemente del codice che li usa. Un caso importante in cui tale cambiamento è necessario sono i test.


142
2018-01-06 18:33



Immaginiamo che tu voglia andare a pescare:

  • Senza l'iniezione di dipendenza, è necessario prendersi cura di tutto da soli. Devi trovare una barca, comprare una canna da pesca, cercare esche, ecc. È possibile, certo, ma ti mette molta responsabilità. In termini di software, significa che devi eseguire una ricerca per tutte queste cose.

  • Con l'iniezione di dipendenza, qualcun altro si occupa di tutta la preparazione e mette a disposizione l'attrezzatura necessaria. Riceverai ("essere iniettato") la barca, la canna da pesca e l'esca - tutto pronto per l'uso.


96
2017-10-22 04:47



Questo è la spiegazione più semplice su Iniezione di dipendenza e Contenitore di iniezione delle dipendenze Che abbia mai visto:

Senza iniezione di dipendenza

  • L'applicazione ha bisogno di Foo (ad esempio un controller), quindi:
  • L'applicazione crea Foo
  • L'applicazione chiama Foo
    • Foo ha bisogno di Bar (ad esempio un servizio), quindi:
    • Foo crea Bar
    • Foo chiama Bar
      • Bar ha bisogno di Bim (un servizio, un deposito, …), così:
      • Bar crea Bim
      • Bar fa qualcosa

Con iniezione di dipendenza

  • L'applicazione ha bisogno di Foo, che ha bisogno di Bar, che ha bisogno di Bim, quindi:
  • L'applicazione crea Bim
  • L'applicazione crea una barra e la dà Bim
  • L'applicazione crea Foo e dà Bar
  • L'applicazione chiama Foo
    • Foo chiama Bar
      • Bar fa qualcosa

Utilizzo di un contenitore per iniezione di dipendenza

  • L'applicazione ha bisogno di Foo così:
  • L'applicazione ottiene Foo dal contenitore, quindi:
    • Il contenitore crea Bim
    • Il contenitore crea una barra e la dà Bim
    • Container crea Foo e gli dà Bar
  • L'applicazione chiama Foo
    • Foo chiama Bar
      • Bar fa qualcosa

Iniezione di dipendenza e contenitori di iniezione di dipendenza sono cose diverse:

  • La dipendenza dall'iniezione è un metodo per scrivere un codice migliore
  • un contenitore DI è uno strumento per aiutare a iniettare dipendenze

Non hai bisogno di un contenitore per fare l'iniezione di dipendenza. Tuttavia un contenitore può aiutarti.


80
2018-05-05 11:53



Proviamo un semplice esempio con Auto e Motore classi, qualsiasi auto ha bisogno di un motore per andare ovunque, almeno per ora. Quindi sotto come apparirà il codice senza iniezione di dipendenza.

public class Car
{
    public Car()
    {
        GasEngine engine = new GasEngine();
        engine.Start();
    }
}

public class GasEngine
{
    public void Start()
    {
        Console.WriteLine("I use gas as my fuel!");
    }
}

E per istanziare la classe Car useremo il prossimo codice:

Car car = new Car();

Il problema con questo codice che abbiamo strettamente associato a GasEngine e se decidiamo di cambiarlo in ElectricityEngine, allora dovremo riscrivere la classe Car. E più grande è l'applicazione, più problemi e mal di testa dovremo aggiungere e usare un nuovo tipo di motore.

In altre parole, con questo approccio, la nostra classe Car di alto livello dipende dalla classe GasEngine di livello inferiore che viola il principio di inversione delle dipendenze (DIP) da SOLID. Il DIP suggerisce che dovremmo dipendere dalle astrazioni, non dalle lezioni concrete. Quindi per soddisfare questo, introduciamo l'interfaccia IEngine e riscriviamo il codice come di seguito:

    public interface IEngine
    {
        void Start();
    }

    public class GasEngine : IEngine
    {
        public void Start()
        {
            Console.WriteLine("I use gas as my fuel!");
        }
    }

    public class ElectricityEngine : IEngine
    {
        public void Start()
        {
            Console.WriteLine("I am electrocar");
        }
    }

    public class Car
    {
        private readonly IEngine _engine;
        public Car(IEngine engine)
        {
            _engine = engine;
        }

        public void Run()
        {
            _engine.Start();
        }
    }

Ora la nostra classe Car dipende solo dall'interfaccia IEngine, non da un'implementazione specifica del motore. Ora, l'unico trucco è come creare un'istanza della macchina e dargli una classe concreta di motore come GasEngine o ElectricityEngine. Ecco dove Iniezione di dipendenza entra.

   Car gasCar = new Car(new GasEngine());
   gasCar.Run();
   Car electroCar = new Car(new ElectricityEngine());
   electroCar.Run();

Qui fondamentalmente iniettiamo (passiamo) la nostra dipendenza (istanza del motore) al costruttore di automobili. Così ora le nostre classi hanno un accoppiamento lento tra gli oggetti e le loro dipendenze, e possiamo facilmente aggiungere nuovi tipi di motori senza cambiare la classe Car.

Il principale vantaggio del Iniezione di dipendenza quelle classi sono più liberamente accoppiate, perché non hanno dipendenze hard-coded. Questo segue il principio di inversione della dipendenza, che è stato menzionato sopra. Invece di fare riferimento a specifiche implementazioni, le classi richiedono astrazioni (di solito interfacce) che sono forniti a loro quando la classe è costruita.

Quindi alla fine Iniezione di dipendenza è solo una tecnica per   ottenere un accoppiamento lento tra gli oggetti e le loro dipendenze.   Piuttosto che creare direttamente delle dipendenze di cui la classe ha bisogno   Per eseguire le sue azioni, le dipendenze sono fornite alla classe   (più spesso) tramite iniezione del costruttore.

Anche quando abbiamo molte dipendenze è molto buona pratica usare i contenitori di Inversion of Control (IoC) che possiamo dire quali interfacce devono essere mappate su quali implementazioni concrete per tutte le nostre dipendenze e possiamo far sì che risolva quelle dipendenze per noi quando costruisce il nostro oggetto. Ad esempio, potremmo specificare nella mappatura per il contenitore IoC che il IEngine la dipendenza dovrebbe essere mappata al GasEngine classe e quando chiediamo al contenitore IoC un'istanza del nostro Auto classe, costruirà automaticamente il nostro Auto classe con a GasEngine dipendenza passata.

AGGIORNARE: Ho seguito recentemente un corso su EF Core da Julie Lerman e mi è anche piaciuta la sua breve definizione su DI.

L'iniezione di dipendenza è uno schema che consente di iniettare l'applicazione   oggetti al volo per le classi che ne hanno bisogno, senza forzare quelli   classi per essere responsabili di quegli oggetti. Permette al tuo codice di essere   più liberamente accoppiati e Entity Framework Core si collega a questo stesso   sistema di servizi.


77
2017-07-06 09:42



Non "iniezione di dipendenza" significa solo l'uso di costruttori parametrizzati e di setter pubblici?

L'articolo di James Shore mostra i seguenti esempi per il confronto.

Costruttore senza iniezione di dipendenza:

public class Example { 
  private DatabaseThingie myDatabase; 

  public Example() { 
    myDatabase = new DatabaseThingie(); 
  } 

  public void doStuff() { 
    ... 
    myDatabase.getData(); 
    ... 
  } 
} 

Costruttore con iniezione di dipendenza:

public class Example { 
  private DatabaseThingie myDatabase; 

  public Example(DatabaseThingie useThisDatabaseInstead) { 
    myDatabase = useThisDatabaseInstead; 
  }

  public void doStuff() { 
    ... 
    myDatabase.getData(); 
    ... 
  } 
}

44
2018-05-02 00:40



Che cos'è Dipendenza Iniezione (DI)?

Come altri hanno detto, Iniezione delle dipendenze (DI) rimuove la responsabilità della creazione diretta e della gestione della durata di vita di altre istanze oggetto da cui dipende la nostra classe di interesse (classe di consumo) (nel Senso di UML). Queste istanze vengono invece passate alla nostra classe consumer, in genere come parametri del costruttore o tramite i setter di proprietà (la gestione dell'oggetto di dipendenza che viene instanziata e passata alla classe consumer viene solitamente eseguita da un Inversion of Control (IoC) contenitore, ma questo è un altro argomento).

DI, DIP e SOLID

Nello specifico, nel paradigma di Robert C Martin Principi solidi del design orientato agli oggetti, DI è una delle possibili implementazioni del Dependency Inversion Principle (DIP). Il DIP è il D del SOLID Mantra  - Altre implementazioni DIP includono il localizzatore del servizio e i modelli di plugin.

L'obiettivo del DIP è quello di disaccoppiare le dipendenze strette e concrete tra le classi e, invece, di allentare l'accoppiamento mediante un'astrazione, che può essere ottenuta tramite un interface, abstract class o pure virtual class, a seconda della lingua e dell'approccio utilizzato.

Senza il DIP, il nostro codice (che ho chiamato questa "classe consumatrice") è direttamente accoppiato a una dipendenza concreta ed è spesso gravato dalla responsabilità di sapere come ottenere e gestire un'istanza di questa dipendenza, cioè concettualmente:

"I need to create/use a Foo and invoke method `GetBar()`"

Considerando che dopo l'applicazione del DIP, il requisito è allentato, e la preoccupazione di ottenere e gestire la durata della vita del Foo la dipendenza è stata rimossa:

"I need to invoke something which offers `GetBar()`"

Perché usare DIP (e DI)?

Il disaccoppiamento delle dipendenze tra le classi in questo modo lo consente facile sostituzione di queste classi di dipendenza con altre implementazioni che soddisfano anche i prerequisiti dell'astrazione (ad esempio la dipendenza può essere cambiata con un'altra implementazione della stessa interfaccia). Inoltre, come altri hanno già detto, forse il La ragione più comune per separare le classi tramite il DIP è consentire a una classe consumante di essere testata in isolamento, poiché queste stesse dipendenze possono ora essere testate e / o derise.

Una conseguenza di DI è che la gestione della durata delle istanze di oggetti di dipendenza non è più controllata da una classe di consumo, poiché l'oggetto di dipendenza viene ora passato nella classe di consumo (tramite la funzione di costruzione o l'iniezione di setter).

Questo può essere visualizzato in diversi modi:

  • Se è necessario mantenere il controllo della durata delle dipendenze da parte della classe di consumo, il controllo può essere ristabilito iniettando un factory (astratto) per la creazione delle istanze della classe di dipendenza, nella classe consumer. Il consumatore sarà in grado di ottenere istanze tramite a Create in fabbrica, se necessario, e smaltire queste istanze una volta complete.
  • Oppure, il controllo della durata di vita delle istanze di dipendenza può essere ceduto a un contenitore IoC (maggiori informazioni al riguardo qui sotto).

Quando usare DI?

  • Dove ci sarà probabilmente la necessità di sostituire una dipendenza per un'implementazione equivalente,
  • Qualsiasi momento in cui sarà necessario testare i metodi di una classe in isolamento delle sue dipendenze,
  • Dove l'incertezza della durata della vita di una dipendenza può giustificare una sperimentazione (per esempio, Hey, MyDepClass è thread-safe - cosa succede se lo rendiamo un singleton e iniettiamo la stessa istanza in tutti i consumatori?)

Esempio

Ecco una semplice implementazione di C #. Data la classe di consumo sottostante:

public class MyLogger
{
   public void LogRecord(string somethingToLog)
   {
      Console.WriteLine("{0:HH:mm:ss} - {1}", DateTime.Now, somethingToLog);
   }
}

Sebbene apparentemente innocuo, ne ha due static dipendenze da altre due classi, System.DateTime e System.Console, che non limitano solo le opzioni di output di registrazione (il logging alla console sarà inutile se nessuno sta guardando), ma peggio, è difficile testare automaticamente data la dipendenza da un clock di sistema non deterministico.

Possiamo tuttavia applicare DIP a questa classe, estrapolando la preoccupazione del timestamping come dipendenza e accoppiamento MyLogger solo per una semplice interfaccia:

public interface IClock
{
    DateTime Now { get; }
}

Possiamo anche allentare la dipendenza da Console a un'astrazione, come a TextWriter. In genere, l'iniezione di dipendenza viene implementata come entrambi constructor iniezione (passando un'astrazione a una dipendenza come parametro al costruttore di una classe consumatrice) o Setter Injection (passando la dipendenza tramite a setXyz() setter o una proprietà .Net con {set;} definito). È preferibile l'Injection del costruttore, in quanto garantisce che la classe si trovi in ​​uno stato corretto dopo la costruzione e consente di contrassegnare i campi di dipendenza interni come readonly (C #) o final (Giava). Quindi, usando l'iniezione del costruttore nell'esempio sopra, questo ci lascia con:

public class MyLogger : ILogger // Others will depend on our logger.
{
    private readonly TextWriter _output;
    private readonly IClock _clock;

    // Dependencies are injected through the constructor
    public MyLogger(TextWriter stream, IClock clock)
    {
        _output = stream;
        _clock = clock;
    }

    public void LogRecord(string somethingToLog)
    {
        // We can now use our dependencies through the abstraction 
        // and without knowledge of the lifespans of the dependencies
        _output.Write("{0:yyyy-MM-dd HH:mm:ss} - {1}", _clock.Now, somethingToLog);
    }
}

(Un concreto Clock deve essere fornito, che naturalmente potrebbe tornare a DateTime.Nowe le due dipendenze devono essere fornite da un contenitore IoC tramite l'iniezione del costruttore)

È possibile creare un Unit Test automatizzato, che dimostra definitivamente che il nostro logger funziona correttamente, poiché ora abbiamo il controllo sulle dipendenze - il tempo e possiamo spiare l'output scritto:

[Test]
public void LoggingMustRecordAllInformationAndStampTheTime()
{
    // Arrange
    var mockClock = new Mock<IClock>();
    mockClock.Setup(c => c.Now).Returns(new DateTime(2015, 4, 11, 12, 31, 45));
    var fakeConsole = new StringWriter();

    // Act
    new MyLogger(fakeConsole, mockClock.Object)
        .LogRecord("Foo");

    // Assert
    Assert.AreEqual("2015-04-11 12:31:45 - Foo", fakeConsole.ToString());
}

Prossimi passi

L'iniezione di dipendenza è invariabilmente associata a un Inversion of Control container (IoC), per iniettare (fornire) le istanze di dipendenza concrete e per gestire le istanze di durata. Durante il processo di configurazione / bootstrap, IoC i contenitori consentono di definire quanto segue:

  • mappatura tra ciascuna astrazione e l'implementazione concreta configurata (ad es. "ogni volta che un consumatore richiede un IBar, restituire a ConcreteBar esempio")
  • le politiche possono essere impostate per la gestione della vita di ogni dipendenza, ad es. per creare un nuovo oggetto per ogni istanza consumer, per condividere un'istanza di dipendenza singleton tra tutti i consumatori, per condividere la stessa istanza di dipendenza solo attraverso lo stesso thread, ecc.
  • In .Net, i contenitori IoC sono a conoscenza di protocolli come IDisposable e si assumerà la responsabilità di Disposing dipendenze in linea con la gestione della durata della vita configurata.

Tipicamente, una volta che i contenitori IoC sono stati configurati / bootstrap, operano senza interruzioni in background consentendo al programmatore di concentrarsi sul codice in questione piuttosto che preoccuparsi delle dipendenze.

La chiave per il codice DI-friendly è evitare l'accoppiamento statico delle classi e non usare new () per la creazione di dipendenze

Come per l'esempio precedente, il disaccoppiamento delle dipendenze richiede uno sforzo progettuale e per lo sviluppatore è necessario uno spostamento di paradigma per rompere l'abitudine di newdipendendo direttamente dalle dipendenze e affidandosi invece al contenitore per gestire le dipendenze.

Ma i benefici sono molti, specialmente nella capacità di testare accuratamente la vostra classe di interesse.

Nota : La creazione / mappatura / proiezione (via new ..()) di PTO / POJO / DTO di serializzazione / Grafici di entità / Proiezioni JSON anonime et al - cioè "Classi o record di solo dati" - utilizzati o restituiti dai metodi non considerato come Dipendenze (nel senso di UML) e non soggetto a DI. utilizzando new proiettarli va bene.


35
2018-04-28 20:17