Inversione del controllo vs iniezione di dipendenza


525

Secondo l' articolo scritto da Martin Fowler , l'inversione del controllo è il principio in cui viene invertito il flusso di controllo di un programma: invece del programmatore che controlla il flusso di un programma, le fonti esterne (framework, servizi, altri componenti) assumono il controllo di esso. È come collegare qualcosa a qualcos'altro. Ha citato un esempio su EJB 2.0:

Ad esempio, l'interfaccia Session Bean definisce ejbRemove, ejbPassivate (archiviato in memoria secondaria) ed ejbActivate (ripristinato dallo stato passivo). Non puoi controllare quando vengono chiamati questi metodi, proprio quello che fanno. Il contenitore ci chiama, noi non lo chiamiamo.

Ciò porta alla differenza tra framework e libreria:

Inversion of Control è una parte fondamentale di ciò che rende un framework diverso da una libreria. Una biblioteca è essenzialmente un insieme di funzioni che puoi chiamare, oggigiorno di solito organizzate in classi. Ogni chiamata fa un po 'di lavoro e restituisce il controllo al client.

Penso che il punto di vista che DI sia IOC, significhi che la dipendenza di un oggetto è invertita: invece di controllarne le dipendenze, il ciclo di vita ... qualcos'altro lo fa per te. Ma, come mi hai detto di DI a mano, DI non è necessariamente IOC. Possiamo ancora avere DI e nessun CIO.

Tuttavia, in questo documento (dalla pococapsule, un altro Framework IOC per C / C ++), suggerisce che a causa di IOC e DI, i contenitori IOC e i framework DI sono molto più superiori a J2EE, poiché J2EE mescola il codice framework nei componenti , quindi non lo rende Plain Old Java / C ++ Object (POJO / POCO).

Inversione di contenitori di controllo diversi dal modello di iniezione di dipendenza (collegamento archivio)

Letture aggiuntive per capire qual è il problema con il vecchio Framework di sviluppo basato sui componenti, che porta al secondo documento sopra: Perché e cosa di Inversion of Control (collegamento Archivio)

La mia domanda : che cosa sono esattamente IOC e DI? Sono confuso. Basato su pococapsule, IOC è qualcosa di più significativo della semplice inversione del controllo tra oggetti o programmatori e framework.


2
Ecco un buon articolo sull'argomento, IoC vs DI (Dependency Inject) vs SL (Service Locator): tinyurl.com/kk4be58 - Estratto dall'URL: IoC vs DI (Dependency Injection)? IoC è il concetto generale in cui il controllo del flusso viene invertito dal codice client al framework, che "fa qualcosa per il client". SL (Service Locator) e DI (Dependency Injection) sono due modelli di progettazione derivati ​​dall'IoC.
Swab.Jat

Per aggiungere i miei due centesimi, se uno è interessato a come l'iniezione di dipendenza può essere utile nel tema di una caffetteria, ho scritto un articolo su questo qui: digigene.com/design-patterns/dependency-injection-coffeeshop
Ali Nem


Inversione di dipendenza: dipende dalle astrazioni, non dalle concrezioni. Inversione del controllo: principale vs astrazione e come il principale è la colla dei sistemi. Questi sono alcuni buoni post che parlano di questo: coderstower.com/2019/03/26/… coderstower.com/2019/04/02/… coderstower.com/2019/04/09/…
Daniel Andres Pelaez Lopez

leggere su questo profondo, Sarà cancellare tutti martinfowler.com/articles/...
Dushman

Risposte:


644

IoC è un termine generico che significa piuttosto che l'applicazione chiama i metodi in un framework, il framework chiama implementazioni fornite dall'applicazione.

DI è una forma di IoC, in cui le implementazioni vengono passate in un oggetto attraverso costruttori / setter / ricerche di servizi, da cui l'oggetto "dipenderà" per comportarsi correttamente.

IoC senza utilizzare DI , ad esempio, sarebbe il modello di modello perché l'implementazione può essere modificata solo tramite la sottoclasse.

DI Frameworks è progettato per utilizzare DI e può definire interfacce (o Annotazioni in Java) per facilitare il passaggio delle implementazioni.

I contenitori IoC sono framework DI che possono funzionare al di fuori del linguaggio di programmazione. In alcuni è possibile configurare quali implementazioni utilizzare nei file di metadati (ad es. XML) che sono meno invasivi. Con un po 'si può fare IoC che normalmente sarebbe impossibile come iniettare un'implementazione a pointcut .

Vedi anche questo articolo di Martin Fowler .


2
Grazie per la risposta. Ma l'altro documento suggerisce che con IOC, i contenitori IOC sono molto più superiori a EJB, mentre Martin Fowler suggerisce che EJB è un tipico esempio di IOC.
Amumu,

5
La gestione del bean è davvero un tipico esempio di IoC. Lo si può vedere dal fatto che il ciclo di vita di un bean è gestito dal contenitore, non dal programmatore. Il programmatore non crea o distrugge un'istanza EJB perché il controllo è delegato al server . Questo è il concetto di IoC: il codice esterno controlla quando viene chiamato il tuo codice, che di solito è l' inverso di ciò che è stato fatto la maggior parte delle volte.
Brandizzi,

2
IoC è un termine generico che significa piuttosto che l'applicazione chiama i metodi in un framework, il framework chiama implementazioni fornite dall'applicazione. Puoi spiegarci di più su questo?
Imad Alazani,

21
Al principio di Hollywood , "non chiamarci, ti chiameremo". Lascia l'invocazione al framework anziché all'applicazione.
Garrett Hall,

@ImadAlazani, faresti meglio a leggere l'articolo che Garrett ha allegato, che è una discussione dettagliata sull'inversione del controllo dal codice dell'applicazione al framework.
MengT

210

In breve, IoC è un termine molto più ampio che include, ma non è limitato a, DI

Il termine Inversion of Control (IoC) originariamente significava qualsiasi tipo di stile di programmazione in cui un framework generale o run-time controllava il flusso del programma

Prima che DI avesse un nome, le persone iniziarono a fare riferimento a quadri che gestiscono le dipendenze come inversione dei contenitori di controllo e presto il significato di IoC si spostò gradualmente verso quel particolare significato: inversione del controllo sulle dipendenze.

Inversion of Control (IoC) significa che gli oggetti non creano altri oggetti su cui si basano per fare il loro lavoro. Al contrario, ottengono gli oggetti di cui hanno bisogno da una fonte esterna (ad esempio, un file di configurazione XML).

Dependency Injection (DI) significa che questo viene fatto senza l'intervento dell'oggetto, di solito da un componente del framework che passa i parametri del costruttore e imposta le proprietà.


1
Sembra che IoC sia solo un altro termine per il principio di inversione di dipendenza, no?
Todd Vance,

@ToddVance - Sì, penso che IoC e DIP siano la stessa cosa. DIP e DI non sono la stessa cosa. IoC può essere eseguito senza DI, ma DI non può essere eseguito senza IoC.
Eljay,

2
@ToddVance - No, DIP e IoC non sono sinonimi e non sono correlati.
TSmith,

3
Ah, ecco perché sono qui su questo thread ... "Inversion of Control vs Dependency Injection"
Todd Vance

50

inserisci qui la descrizione dell'immagine
fonte

IOC ( I nVersione o F C ontrollo): - E 'un termine generico e realizzato in diversi modi (eventi, delegati ecc).

DI ( D ependency I njection): - DI è un sottotipo di IoC ed è implementato tramite iniezione del costruttore, iniezione del setter o iniezione dell'interfaccia .

Ma Spring supporta solo i seguenti due tipi:

  • Iniezione Setter
    • Il DI basato su setter viene realizzato chiamando i metodi setter sui bean dell'utente dopo aver richiamato un costruttore no-argomento o un metodo factory statico senza argomento per istanziare il loro bean.
  • Iniezione Costruttore
    • Il DI basato sul costruttore viene realizzato invocando un costruttore con un numero di argomenti, ognuno dei quali rappresenta un collaboratore. In questo modo possiamo convalidare che i bean iniettati non sono nulli e falliscono velocemente (falliscono in fase di compilazione e non in run-time), quindi all'avvio dell'applicazione stessa otteniamo NullPointerException: bean does not exist. L'iniezione del costruttore è la migliore pratica per iniettare dipendenze.

1
non è corretto affermando che Spring non supporta l'iniezione di proprietà. Lo fa. Ed è una cattiva pratica, sono d'accordo.
kekko12,

L'annotazione Spring @Autowired è un modo di iniezione di proprietà secondo me
Sajith

49

DI è un sottoinsieme di IoC

  • IoC significa che gli oggetti non creano altri oggetti su cui si basano per fare il loro lavoro. Al contrario, ottengono gli oggetti di cui hanno bisogno da un servizio esterno (ad esempio, file xml o servizio di app singola). 2 implementazioni di IoC, utilizzo, sono DI e ServiceLocator.
  • DI significa che il principio IoC di ottenere l'oggetto dipendente viene fatto senza usare oggetti concreti ma astrazioni (interfacce). Questo rende testabili tutti i componenti della catena, poiché il componente di livello superiore non dipende dal componente di livello inferiore, ma solo dall'interfaccia. Le simulazioni implementano queste interfacce.

Ecco alcune altre tecniche per raggiungere l'IoC .


Non direi che IoC significhi non creare oggetti. Quando si chiama non direttamente il metodo di classe, ma il metodo di interfaccia - questa è inversione di controllo (come in questo caso il chiamante non dipende dal codice chiamante) e non è affatto correlato alla creazione di oggetti. Un altro esempio di IoC sono eventi e delegati
Eugene Gorbovoy,

20

IOC (Inversion Of Control) : dare controllo al contenitore per ottenere un'istanza dell'oggetto si chiama Inversion of Control, significa che invece di creare un oggetto usando il nuovo operatore, lascia che il contenitore lo faccia per te.

DI (Iniezione delle dipendenze) : il modo di iniettare proprietà in un oggetto è chiamato Iniezione delle dipendenze .

Abbiamo tre tipi di iniezione di dipendenza :

  1. Iniezione Costruttore
  2. Iniezione setter / getter
  3. Iniezione di interfaccia

Spring supporta solo l' iniezione di costruttori e l' iniezione di setter / getter .


19

Poiché tutte le risposte enfatizzano la teoria, vorrei dimostrare con un primo approccio di esempio:

Supponiamo che stiamo costruendo un'applicazione che contiene una funzione per inviare messaggi di conferma SMS una volta che l'ordine è stato spedito. Avremo due classi, una è responsabile dell'invio dell'SMS (SMSService) e un'altra è responsabile dell'acquisizione degli input dell'utente (UIHandler), il nostro codice apparirà come di seguito:

public class SMSService
{
    public void SendSMS(string mobileNumber, string body)
    {
        SendSMSUsingGateway(mobileNumber, body);
    }

    private void SendSMSUsingGateway(string mobileNumber, string body)
    {
        /*implementation for sending SMS using gateway*/
    }
}

public class UIHandler
{
    public void SendConfirmationMsg(string mobileNumber)
    {
        SMSService _SMSService = new SMSService();
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

L'implementazione sopra non è sbagliata ma ci sono alcuni problemi:
-) Supponiamo che, in questo ambiente di sviluppo, si desideri salvare gli SMS inviati a un file di testo anziché utilizzare il gateway SMS; finiremo per cambiare l'implementazione concreta di (SMSService) con un'altra implementazione, stiamo perdendo flessibilità e in questo caso siamo costretti a riscrivere il codice.
-) Finiremo per mescolare le responsabilità delle classi, il nostro (UIHandler) non dovrebbe mai conoscere l'implementazione concreta di (SMSService), questo dovrebbe essere fatto al di fuori delle classi usando "Interfacce". Quando questo è implementato, ci darà la possibilità di cambiare il comportamento del sistema scambiando il (SMSService) utilizzato con un altro servizio simulato che implementa la stessa interfaccia, questo servizio salverà gli SMS in un file di testo invece di inviarli a mobileNumber.

Per risolvere i problemi di cui sopra utilizziamo le interfacce che saranno implementate dal nostro (SMSService) e dal nuovo (MockSMSService), in sostanza la nuova interfaccia (ISMSService) esporrà gli stessi comportamenti di entrambi i servizi del codice seguente:

public interface ISMSService
{
    void SendSMS(string phoneNumber, string body);
}

Quindi cambieremo la nostra implementazione (SMSService) per implementare l'interfaccia (ISMSService):

public class SMSService : ISMSService
{
    public void SendSMS(string mobileNumber, string body)
    {
        SendSMSUsingGateway(mobileNumber, body);
    }

    private void SendSMSUsingGateway(string mobileNumber, string body)
    {
        /*implementation for sending SMS using gateway*/
        Console.WriteLine("Sending SMS using gateway to mobile: 
        {0}. SMS body: {1}", mobileNumber, body);
    }
}

Ora saremo in grado di creare un nuovo servizio di simulazione (MockSMSService) con un'implementazione totalmente diversa utilizzando la stessa interfaccia:

public class MockSMSService :ISMSService
{
    public void SendSMS(string phoneNumber, string body)
    {
        SaveSMSToFile(phoneNumber,body);
    }

    private void SaveSMSToFile(string mobileNumber, string body)
    {
        /*implementation for saving SMS to a file*/
        Console.WriteLine("Mocking SMS using file to mobile: 
        {0}. SMS body: {1}", mobileNumber, body);
    }
}

A questo punto, possiamo modificare il codice in (UIHandler) per utilizzare l'implementazione concreta del servizio (MockSMSService) facilmente come di seguito:

public class UIHandler
{
    public void SendConfirmationMsg(string mobileNumber)
    {
        ISMSService _SMSService = new MockSMSService();
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

Abbiamo raggiunto molta flessibilità e implementato la separazione delle preoccupazioni nel nostro codice, ma dobbiamo ancora modificare la base di codice per passare da un servizio SMS all'altro. Quindi dobbiamo implementare l' iniezione delle dipendenze .

Per raggiungere questo obiettivo, dobbiamo implementare una modifica al nostro costruttore della classe (UIHandler) per far passare la dipendenza attraverso di essa, in questo modo, il codice che utilizza (UIHandler) può determinare quale implementazione concreta di (ISMSService) utilizzare:

public class UIHandler
{
    private readonly ISMSService _SMSService;

    public UIHandler(ISMSService SMSService)
    {
        _SMSService = SMSService;
    }

    public void SendConfirmationMsg(string mobileNumber)
    {
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

Ora il modulo UI che parlerà con la classe (UIHandler) è responsabile del passaggio dell'implementazione dell'interfaccia (ISMSService) da utilizzare. Ciò significa che abbiamo invertito il controllo, (UIHandler) non è più responsabile di decidere quale implementazione utilizzare, come fa il codice chiamante. Abbiamo implementato il principio di inversione del controllo che DI è un tipo di esso.

Il codice del modulo dell'interfaccia utente sarà il seguente:

class Program
{
    static void Main(string[] args)
    {
        ISMSService _SMSService = new MockSMSService(); // dependency

        UIHandler _UIHandler = new UIHandler(_SMSService);
        _UIHandler.SendConfirmationMsg("96279544480");

        Console.ReadLine();
    }
}

Grande spiegazione
ZiviMagic

5

Ma la documentazione di primavera dice che sono uguali.

http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-introduction

Nella prima riga " IoC è anche noto come iniezione di dipendenza (DI) ".


1
Immagino che ciò che stavano cercando di affrontare sia che DI è un sapore molto usato del modello di progettazione IoC che può quasi facilmente essere chiamato IoC aka DI - a meno che la documentazione non abbia alcun riferimento esplicito che suggerisca diversamente.
ha9u63ar,

5
"IoC è anche noto come iniezione di dipendenza (DI)" ... piume di cavallo!
MikeM,

5

IoC - Inversion of control è un termine generico, indipendente dal linguaggio, in realtà non crea gli oggetti ma descrive in quale oggetto moda viene creato.

DI - Iniezione delle dipendenze è un termine concreto, in cui forniamo dipendenze dell'oggetto in fase di esecuzione utilizzando diverse tecniche di iniezione, vale a dire. Iniezione setter, Iniezione costruttore o Iniezione interfaccia.


4

L'inversione del controllo è un paradigma progettuale con l'obiettivo di dare maggiore controllo ai componenti mirati della tua applicazione, quelli che svolgono il lavoro.
L'iniezione di dipendenza è un modello utilizzato per creare istanze di oggetti su cui fanno affidamento altri oggetti senza sapere in fase di compilazione quale classe verrà utilizzata per fornire quella funzionalità.

Esistono diverse tecniche di base per implementare l'inversione del controllo. Questi sono:

  • Utilizzando un modello di fabbrica
  • Utilizzo di un modello di localizzazione di servizio
  • Utilizzando un'iniezione di dipendenza di qualsiasi tipo indicato di seguito:

    1). Un'iniezione del costruttore
    2). Un'iniezione del setter
    3). Un'iniezione di interfaccia

4

DI e IOC sono due modelli progettuali che si concentrano principalmente sulla fornitura di un accoppiamento libero tra i componenti , o semplicemente un modo in cui si disaccoppiano le relazioni di dipendenza convenzionali tra gli oggetti in modo che gli oggetti non siano stretti l'uno con l'altro.

Con i seguenti esempi, sto cercando di spiegare entrambi questi concetti.

In precedenza scrivevamo codice come questo

Public MyClass{
 DependentClass dependentObject
 /*
  At somewhere in our code we need to instantiate 
  the object with new operator  inorder to use it or perform some method.
  */ 
  dependentObject= new DependentClass();
  dependentObject.someMethod();
}

Con l'iniezione di dipendenza, l'iniettore di dipendenza si occuperà dell'istanza degli oggetti

Public MyClass{
 /* Dependency injector will instantiate object*/
 DependentClass dependentObject

 /*
  At somewhere in our code we perform some method. 
  The process of  instantiation will be handled by the dependency injector
 */ 

  dependentObject.someMethod();
}

Il suddetto processo di dare il controllo a qualcun altro (ad esempio il contenitore) per l'istanziazione e l'iniezione può essere definito come inversione di controllo e il processo in cui il contenitore IOC inietta la dipendenza per noi può essere definito come iniezione di dipendenza.

Il COI è il principio in cui viene invertito il flusso di controllo di un programma: invece del programmatore che controlla il flusso di un programma , il programma controlla il flusso riducendo l'overhead al programmatore. Il processo utilizzato dal programma per iniettare dipendenza è definito come DI

I due concetti lavorano insieme fornendoci un modo per scrivere codice molto più flessibile, riutilizzabile e incapsulato, che li rende concetti importanti nella progettazione di soluzioni orientate agli oggetti.

Consiglio anche di leggere.

Che cos'è l'iniezione di dipendenza?

Puoi anche controllare una delle mie risposte simili qui

Differenza tra inversione di controllo e iniezione di dipendenza


3

Inversion of Control è un principio di progettazione generico dell'architettura software che aiuta a creare framework software riutilizzabili e modulari che sono facili da mantenere.

È un principio di progettazione in cui il flusso di controllo viene "ricevuto" dalla libreria o dal codice riutilizzabile con scrittura generica.

Per capirlo meglio, vediamo come eravamo abituati a programmare nei nostri primi giorni di programmazione. Nei linguaggi procedurali / tradizionali, la logica aziendale generalmente controlla il flusso dell'applicazione e "Chiama" il codice / le funzioni generiche o riutilizzabili. Ad esempio, in una semplice applicazione Console, il mio flusso di controllo è controllato dalle istruzioni del mio programma, che possono includere le chiamate ad alcune funzioni generali riutilizzabili.

print ("Please enter your name:");
scan (&name);
print ("Please enter your DOB:");
scan (&dob);

//More print and scan statements
<Do Something Interesting>

//Call a Library function to find the age (common code)
print Age

Al contrario, con IoC, i frame sono il codice riutilizzabile che "chiama" la logica aziendale.

Ad esempio, in un sistema basato su Windows, sarà già disponibile un framework per creare elementi dell'interfaccia utente come pulsanti, menu, finestre e finestre di dialogo. Quando scrivo la logica aziendale della mia applicazione, sarebbero gli eventi del framework che chiameranno il mio codice di logica aziendale (quando viene generato un evento) e NON il contrario.

Sebbene, il codice del framework non sia a conoscenza della mia logica aziendale, saprà comunque come chiamare il mio codice. Ciò si ottiene utilizzando eventi / delegati, callback ecc. Qui il controllo del flusso è "Invertito".

Pertanto, anziché dipendere dal flusso di controllo sugli oggetti associati staticamente, il flusso dipende dal grafico generale dell'oggetto e dalle relazioni tra oggetti diversi.

Iniezione delle dipendenze è un modello di progettazione che implementa il principio IoC per risolvere le dipendenze degli oggetti.

In parole più semplici, quando si tenta di scrivere codice, si creano e si usano classi diverse. Una classe (Classe A) può utilizzare altre classi (Classe B e / o D). Pertanto, le classi B e D sono dipendenze della classe A.

Una semplice analogia sarà un'auto di classe. Un'auto potrebbe dipendere da altre classi come Motore, Pneumatici e altro.

Injection Dependency suggerisce che invece delle classi Dependent (Class Car qui) che creano le sue dipendenze (Class Engine e class Tire), la classe dovrebbe essere iniettata con l'istanza concreta della dipendenza.

Comprendiamo con un esempio più pratico. Considera che stai scrivendo il tuo TextEditor. Tra le altre cose, puoi avere un controllo ortografico che fornisce all'utente una funzione per controllare gli errori di battitura nel suo testo. Una semplice implementazione di tale codice può essere:

Class TextEditor
{

    //Lot of rocket science to create the Editor goes here

    EnglishSpellChecker objSpellCheck;
    String text;

    public void TextEditor()

    {   

        objSpellCheck = new EnglishSpellChecker();

    }

    public ArrayList <typos> CheckSpellings()
    {

        //return Typos;

    }

}

A prima vista, tutto sembra roseo. L'utente scriverà del testo. Lo sviluppatore acquisirà il testo e chiamerà la funzione CheckSpellings e troverà un elenco di Typos che mostrerà all'utente.

Tutto sembra funzionare alla grande fino a un bel giorno in cui un utente inizia a scrivere il francese nell'editor.

Per fornire il supporto per più lingue, dobbiamo disporre di più SpellChecker. Probabilmente francese, tedesco, spagnolo ecc.

Qui, abbiamo creato un codice strettamente accoppiato con SpellChecker "inglese" strettamente accoppiato con la nostra classe TextEditor, il che significa che la nostra classe TextEditor dipende da EnglishSpellChecker o in altre parole EnglishSpellCheker è la dipendenza per TextEditor. Dobbiamo rimuovere questa dipendenza. Inoltre, il nostro editor di testo ha bisogno di un modo per conservare il riferimento concreto di qualsiasi correttore ortografico basato sulla discrezione dello sviluppatore in fase di esecuzione.

Quindi, come abbiamo visto nell'introduzione di DI, suggerisce che la classe dovrebbe essere iniettata con le sue dipendenze. Quindi, dovrebbe essere responsabilità del codice chiamante iniettare tutte le dipendenze nella classe / codice chiamato. Quindi possiamo ristrutturare il nostro codice come

interface ISpellChecker
{

    Arraylist<typos> CheckSpelling(string Text);

}

Class EnglishSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}



Class FrenchSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}

Nel nostro esempio, la classe TextEditor dovrebbe ricevere l'istanza concreta del tipo ISpellChecker.

Ora, la dipendenza può essere iniettata in Costruttore, una proprietà pubblica o un metodo.

Proviamo a cambiare la nostra classe usando il costruttore DI. La classe TextEditor modificata sarà simile a:

Class TextEditor

{

    ISpellChecker objSpellChecker;

    string Text;



    public void TextEditor(ISpellChecker objSC)

    {

        objSpellChecker = objSC;

    }



    public ArrayList <typos> CheckSpellings()

    {

        return objSpellChecker.CheckSpelling();

    }

}

In modo che il codice chiamante, durante la creazione dell'editor di testo, possa iniettare il tipo di SpellChecker appropriato nell'istanza di TextEditor.

Puoi leggere l'articolo completo qui


3

IOC (Inversion Of Control): Dare controllo al contenitore per ottenere l'istanza dell'oggetto è chiamato Inversion of Control. Significa che invece di creare oggetti utilizzando un nuovo operatore , lascia che il contenitore lo faccia per te.

DI (Iniezione delle dipendenze): il passaggio dei parametri (proprietà) richiesti da XML a un oggetto (in CLASSE POJO) è chiamato iniezione di dipendenza.


2

IOC indica che una classe esterna gestisce le classi di un'applicazione e classi esterne significa che un contenitore gestisce la dipendenza tra la classe di applicazione. il concetto base di IOC è che il programmatore non ha bisogno di creare i tuoi oggetti ma descrive come dovrebbero essere creati.

Le attività principali eseguite dal contenitore IoC sono: istanziare la classe dell'applicazione. per configurare l'oggetto. per assemblare le dipendenze tra gli oggetti.

DI è il processo di fornire le dipendenze di un oggetto in fase di esecuzione utilizzando l'iniezione del setter o l'iniezione del costruttore.


2

Il CIO (Inversion of Control) è fondamentalmente un concetto di modello di progettazione per la rimozione delle dipendenze e il loro disaccoppiamento per rendere il flusso non lineare e consentire al contenitore / o altra entità di gestire il provisioning delle dipendenze. In realtà segue il principio di Hollywood "Non chiamarci, ti chiameremo". Quindi riassumendo le differenze.

Inversione del controllo: - È un termine generico per disaccoppiare le dipendenze e delegare il loro provisioning, e questo può essere implementato in diversi modi (eventi, delegati ecc.).

Iniezione delle dipendenze: - DI è un sottotipo di IOC ed è implementato mediante iniezione del costruttore, iniezione del setter o iniezione del metodo.

Il seguente articolo lo descrive molto bene.

https://www.codeproject.com/Articles/592372/Dependency-Injection-DI-vs-Inversion-of-Control-IO


1

Penso che l'idea possa essere dimostrata chiaramente senza entrare nelle erbacce orientate agli oggetti, che sembrano confondere l'idea.

// dependency injection
function doSomething(dependency) {
    // do something with your dependency
}

// in contrast to creating your dependencies yourself
function doSomething() {
    dependency = getDependencySomehow()
}

// inversion of control
application = makeApp(authenticate, handleRequest, sendResponse)
application.run(getRequest())

// in contrast to direct control or a "library" style
application = makeApp()
request = application.getRequest()

if (application.authenticate(request.creds)) {
    response = application.handleRequest(request)
    application.sendResponse(response)
}

Se inclini la testa e socchiudi gli occhi, vedrai che DI è un'implementazione particolare dell'IoC con preoccupazioni specifiche. Invece di iniettare modelli e comportamenti in un framework di applicazione o operazione di ordine superiore, stai iniettando variabili in una funzione o in un oggetto.


0

Cominciamo con D di SOLID e guardiamo DI e IoC dal libro di Scott Millett "Professional ASP.NET Design Patterns":

Principio di inversione di dipendenza (DIP)

Il DIP consiste nell'isolare le tue classi da implementazioni concrete e farle dipendere da classi o interfacce astratte. Promuove il mantra della codifica in un'interfaccia piuttosto che in un'implementazione, il che aumenta la flessibilità all'interno di un sistema assicurando che non sia strettamente associato a un'unica implementazione.

Dependency Injection (DI) e Inversion of Control (IoC)

Strettamente collegati al DIP sono il principio DI e il principio IoC. DI è l'atto di fornire un livello basso o una classe dipendente tramite un costruttore, un metodo o una proprietà. Utilizzate insieme a DI, queste classi dipendenti possono essere invertite in interfacce o classi astratte che porteranno a sistemi liberamente accoppiati che sono altamente testabili e facili da cambiare.

In IoC , il flusso di controllo di un sistema è invertito rispetto alla programmazione procedurale. Un esempio di ciò è un contenitore IoC , il cui scopo è iniettare servizi nel codice client senza che il codice client specifichi l'implementazione concreta. Il controllo in questa istanza che viene invertito è l'atto del client che ottiene il servizio.

Millett, C (2010). Modelli di progettazione ASP.NET professionali. Wiley Publishing. 7-8.


0

// ICO, DI, 10 anni fa, era così:

public class  AuditDAOImpl implements Audit{

    //dependency
    AuditDAO auditDAO = null;
        //Control of the AuditDAO is with AuditDAOImpl because its creating the object
    public AuditDAOImpl () {
        this.auditDAO = new AuditDAO ();
    }
}

Ora con Spring 3,4 o più recente è come sotto

public class  AuditDAOImpl implements Audit{

    //dependency

     //Now control is shifted to Spring. Container find the object and provide it. 
    @Autowired
    AuditDAO auditDAO = null;

}

Nel complesso, il controllo viene invertito dal vecchio concetto di codice accoppiato ai framework come Spring che rende disponibile l'oggetto. Quindi questo è IOC per quanto ne so e iniezione di dipendenza come sai quando iniettiamo l'oggetto dipendente in un altro oggetto usando Costruttore o setter. Iniettare sostanzialmente significa passarlo come argomento. In primavera abbiamo una configurazione basata su XML e annotazioni in cui definiamo l'oggetto bean e passiamo l'oggetto dipendente con lo stile di iniezione del costruttore o del setter.


0

Ho trovato il miglior esempio su Dzone.com che è davvero utile per capire la vera differenza tra IOC e DI

"IoC è quando hai qualcun altro che crea oggetti per te." Quindi, invece di scrivere una "nuova" parola chiave (ad esempio, MyCode c = new MyCode ()) nel codice, l'oggetto viene creato da qualcun altro. Questo "qualcun altro" viene normalmente definito contenitore IoC. Significa che consegniamo la rrsponsibility (controllo) al contenitore per ottenere l'istanza dell'oggetto che si chiama Inversion of Control. Significa che invece di creare un oggetto utilizzando un nuovo operatore, lascia che il contenitore lo faccia per te.

   DI(Dependency Injection):  Way of injecting properties to an object is 
   called 
  Dependency injection.
   We have three types of Dependency injection
    1)  Constructor Injection
    2)  Setter/Getter Injection
    3)  Interface Injection
   Spring will support only Constructor Injection and Setter/Getter Injection.

Leggi l'articolo completo IOC e leggi l'articolo completo DI


0

1) DI is Child-> obj dipende da parent-obj. Il verbo dipende è importante. 2) IOC è Child-> obj esibirsi sotto una piattaforma. dove piattaforma potrebbe essere la scuola, l'università, la lezione di danza. Qui eseguire è un'attività con implicazioni diverse in qualsiasi provider di piattaforme.

esempio pratico: `

//DI
child.getSchool();
//IOC
child.perform()// is a stub implemented by dance-school
child.flourish()// is a stub implemented by dance-school/school/

`

-AB


0

Per quanto riguarda questa domanda, direi che il wiki ha già fornito spiegazioni dettagliate e di facile comprensione. Citerò solo il più significativo qui.

Implementazione di IoC

Nella programmazione orientata agli oggetti, ci sono diverse tecniche di base per implementare l'inversione del controllo. Questi sono:

  1. Utilizzo di un modello di localizzazione di servizio Utilizzo dell'iniezione di dipendenza, ad esempio Iniezione costruttore Iniezione parametri Iniezione setter Iniezione interfaccia;
  2. Utilizzando una ricerca contestualizzata;
  3. Utilizzo del modello di progettazione del metodo modello;
  4. Utilizzando il modello di progettazione strategica

Per quanto riguarda l' iniezione di dipendenza

l'iniezione di dipendenza è una tecnica con cui un oggetto (o metodo statico) fornisce le dipendenze di un altro oggetto. Una dipendenza è un oggetto che può essere utilizzato (un servizio). Un'iniezione è il passaggio di una dipendenza a un oggetto dipendente (un client) che lo userebbe.


0

Il concetto di IoC è stato inizialmente ascoltato durante l'era della programmazione procedurale. Pertanto, da un contesto storico, l'IoC ha parlato dell'inversione della proprietà del controllo- flusso ovvero di chi possiede la responsabilità di invocare le funzioni nell'ordine desiderato, sia che si tratti delle funzioni stesse sia che si debba invertirla in qualche entità esterna.

Tuttavia, una volta emersa la OOP, le persone hanno iniziato a parlare di IoC nel contesto OOP in cui le applicazioni si occupano anche della creazione di oggetti e delle loro relazioni, a parte il flusso di controllo. Tali applicazioni volevano invertire la proprietà della creazione di oggetti (piuttosto che il flusso di controllo) e richiedevano un contenitore che è responsabile della creazione di oggetti, del ciclo di vita degli oggetti e dell'iniezione di dipendenze degli oggetti dell'applicazione, eliminando così gli oggetti dell'applicazione dalla creazione di altri oggetti concreti.

In questo senso, DI non è lo stesso di Io C , poiché non si tratta di flusso di controllo, tuttavia è una specie di Io * , cioè inversione di proprietà della creazione di oggetti.

Cosa c'è di sbagliato nel mio modo di spiegare DI e IoC?


0

IoC aka Inversion of Control si riferisce al controllo della creazione di istanze che viene eseguito dal contenitore Spring. Il controllo per la creazione e la costruzione di oggetti è curato dal contenitore. Il contenitore crea gli oggetti e li inietta nella nostra applicazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.