Cos’è l’inversione del controllo?

Inversion of Control (o IoC) può essere piuttosto confuso quando viene rilevato per la prima volta.

  1. Che cos’è?
  2. Quali problemi risolve?
  3. Quando è appropriato e quando no?

Gli schemi Inversion of Control (IoC) e Dependency Injection (DI) riguardano esclusivamente la rimozione delle dipendenze dal codice.

Ad esempio, supponi che la tua applicazione abbia un componente di editor di testo e desideri fornire il controllo ortografico. Il tuo codice standard sarebbe simile a questo:

public class TextEditor { private SpellChecker checker; public TextEditor() { this.checker = new SpellChecker(); } } 

Quello che abbiamo fatto qui crea una dipendenza tra TextEditor e SpellChecker . In uno scenario IoC faremmo invece qualcosa del genere:

 public class TextEditor { private IocSpellChecker checker; public TextEditor(IocSpellChecker checker) { this.checker = checker; } } 

Nel primo esempio di codice stiamo istanziando SpellChecker ( this.checker = new SpellChecker(); ), il che significa che la class TextEditor dipende direttamente dalla class SpellChecker .

Nel secondo esempio di codice stiamo creando un’astrazione avendo la class di dipendenza SpellChecker nella firma del costruttore di TextEditor (non inizializzando la dipendenza in class). Questo ci permette di chiamare la dipendenza e poi passarla alla class TextEditor in questo modo:

 SpellChecker sc = new SpellChecker; // dependency TextEditor textEditor = new TextEditor(sc); 

Ora il client che crea la class TextEditor ha il controllo su quale implementazione SpellChecker usare perché stiamo iniettando la dipendenza dalla firma di TextEditor .

Questo è solo un semplice esempio, c’è una buona serie di articoli di Simone Busoli che la spiega in modo più dettagliato.

Inversion of Control è ciò che ottieni quando i callback del programma, ad esempio come un programma GUI.

Ad esempio, in un menu di una vecchia scuola, potresti avere:

 print "enter your name" read name print "enter your address" read address etc... store in database 

controllando in tal modo il stream di interazione dell’utente.

In un programma GUI o somesuch, invece diciamo

 when the user types in field a, store it in NAME when the user types in field b, store it in ADDRESS when the user clicks the save button, call StoreInDatabase 

Quindi ora il controllo è invertito … invece che il computer che accetta l’input dell’utente in un ordine fisso, l’utente controlla l’ordine in cui i dati vengono immessi e quando i dati vengono salvati nel database.

Fondamentalmente, qualsiasi cosa con un ciclo di eventi, callback o trigger di esecuzione rientra in questa categoria.

Cos’è l’inversione del controllo?

Se segui questi semplici due passaggi, hai invertito il controllo:

  1. Separa la parte di cosa -fare da quando parte da fare.
  2. Assicurarsi che quando una parte sappia il meno ansible su quale parte; e viceversa.

Esistono diverse tecniche possibili per ciascuna di queste fasi in base alla tecnologia / lingua che si sta utilizzando per la propria implementazione.

La parte di inversione dell’Inversion of Control (IoC) è la cosa che confonde; perché l’ inversione è il termine relativo. Il modo migliore per capire l’IoC è dimenticare quella parola!

Esempi

  • Gestione degli eventi. Gestori di eventi (cosa da fare) – Raising Events (parte when-to-do)
  • Interfacce. Componente client (parte quando-fare-da-lavoro) – Implementazione dell’interfaccia del componente (parte “cosa-fare”)
  • xFissura di unità. Setup e TearDown (parte what-to-do) – xUnit framework chiama al Setup all’inizio e TearDown alla fine (parte when-to-do)
  • Modello di progettazione del metodo di modello. template method when-to-do part – primitiva implementazione della sottoclass
  • Metodi contenitore DLL in COM. DllMain, DllCanUnload, etc (parte “cosa-fare”) – COM / OS (parte delle cose da fare)

Inversion of Controls riguarda la separazione delle preoccupazioni.

Senza IoC : hai un computer portatile e accidentalmente rompi lo schermo. E maledettamente, lo stesso modello di schermo del laptop non si trova da nessuna parte sul mercato. Quindi sei bloccato.

Con IoC : hai un computer desktop e accidentalmente rompi lo schermo. Scoprirai che puoi prendere quasi tutti i monitor desktop dal mercato e funziona bene con il tuo desktop.

In questo caso il tuo desktop implementa correttamente IoC. Accetta un tipo diverso di monitor, mentre il portatile no, ha bisogno di uno schermo specifico per essere corretto.

Inversion of Control, (o IoC), si tratta di ottenere la libertà (ci si sposa, hai perso la libertà e sei sotto controllo. Hai divorziato, hai appena implementato Inversion of Control. Questo è ciò che abbiamo chiamato “disaccoppiato”. scoraggia una relazione molto stretta.) più flessibilità (la cucina del tuo ufficio serve solo acqua di rubinetto pulita, questa è la tua unica scelta quando vuoi bere.) Il tuo capo ha implementato Inversion of Control impostando una nuova macchina da caffè. flessibilità di scelta tra acqua di rubinetto o caffè.) e meno dipendenza (il vostro partner ha un lavoro, non avete un lavoro, dipendete finanziariamente dal vostro partner, quindi siete controllati. Trovate un lavoro, avete implementato Inversion of Controllo: un buon sistema informatico incoraggia l’interdipendenza).

Quando si utilizza un computer desktop, si è slaved (o dire, controllato). Devi sederti davanti a uno schermo e guardarlo. Usare la tastiera per digitare e usare il mouse per navigare. E un software scritto male può schiavizzarti ancora di più. Se si sostituisce il desktop con un laptop, si verifica un controllo un po ‘invertito. Puoi facilmente prenderlo e muoverti. Quindi ora puoi controllare dove ti trovi con il tuo computer, invece che controllarlo.

Implementando Inversion of Control, un utente software / object ottiene più controlli / opzioni sul software / oggetti, invece di essere controllato o con meno opzioni.

Con le idee di cui sopra in mente. Ci manca ancora una parte fondamentale di IoC. Nello scenario di IoC, il consumatore di software / object è un framework sofisticato. Ciò significa che il codice che hai creato non viene chiamato da te. Ora spieghiamo perché in questo modo funziona meglio per un’applicazione web.

Supponiamo che il tuo codice sia un gruppo di lavoratori. Hanno bisogno di build una macchina. Questi lavoratori hanno bisogno di un posto e di strumenti (una struttura software) per build l’auto. Un framework software tradizionale sarà come un garage con molti strumenti. Quindi i lavoratori devono fare un piano da soli e utilizzare gli strumenti per build l’auto. Costruire una macchina non è un business facile, sarà davvero difficile per i lavoratori pianificare e cooperare in modo appropriato. Una moderna infrastruttura software sarà come una moderna fabbrica di automobili con tutte le strutture e i manager in funzione. I lavoratori non devono fare alcun piano, i manager (parte del framework, sono le persone più intelligenti e hanno fatto il piano più sofisticato) aiuteranno a coordinarsi in modo che i lavoratori sappiano quando fare il loro lavoro (framework chiama il tuo codice). I lavoratori devono solo essere abbastanza flessibili da usare tutti gli strumenti che i manager danno loro (usando Dependency Injection).

Anche se i lavoratori danno il controllo della gestione del progetto al livello più alto ai manager (il framework). Ma è bello avere dei professionisti che aiutano. Questo è il vero concetto di IoC.

Le moderne applicazioni Web con un’architettura MVC dipendono dal framework per eseguire il routing degli URL e mettono in atto i controller per il framework da chiamare.

Iniezione di dipendenza e inversione del controllo sono correlati. L’iniezione delle dipendenze è a livello micro e Inversion of Control è a livello macro . Devi mangiare ogni morso (implementare DI) per terminare un pasto (implementare IoC).

Prima di usare Inversion of Control dovresti essere ben consapevole del fatto che ha i suoi pro e contro e dovresti sapere perché lo usi se lo fai.

Professionisti:

  • Il codice viene disaccoppiato in modo da poter facilmente scambiare le implementazioni di un’interfaccia con implementazioni alternative
  • È un forte motivatore per la codifica contro le interfacce anziché le implementazioni
  • È molto semplice scrivere test unitari per il tuo codice perché non dipende da nient’altro che gli oggetti che accetta nel suo costruttore / setter e puoi facilmente inizializzarli con gli oggetti giusti in isolamento.

Contro:

  • IoC non solo inverte il stream di controllo nel tuo programma, ma lo riduce considerevolmente. Questo significa che non puoi più leggere il tuo codice e saltare da un posto all’altro perché le connessioni che normalmente si trovano nel tuo codice non sono più nel codice. Invece è nei file di configurazione XML o nelle annotazioni e nel codice del tuo contenitore IoC che interpreta questi metadati.
  • Esiste una nuova class di bug in cui si ottiene la configurazione XML o le annotazioni sbagliate e si può dedicare molto tempo a scoprire perché il contenitore IoC inietta un riferimento null in uno dei propri oggetti in determinate condizioni.

Personalmente vedo i punti di forza di IoC e mi piacciono molto ma tendo ad evitare IoC quando ansible perché trasforma il tuo software in una serie di classi che non costituiscono più un programma “reale” ma solo qualcosa che deve essere messo insieme da Configurazione XML o metadati di annotazione e cadrebbe (e cadrà) a parte senza di esso.

  1. Articolo di Wikipedia . Per me, l’inversione di controllo sta trasformando il codice scritto sequenzialmente e trasformandolo in una struttura di delega. Invece del tuo programma che controlla in modo esplicito tutto, il tuo programma imposta una class o una libreria con determinate funzioni da chiamare quando accadono certe cose.

  2. Risolve la duplicazione del codice. Ad esempio, nei vecchi tempi dovresti scrivere manualmente il tuo loop di eventi, interrogando le librerie di sistema per nuovi eventi. Oggigiorno, la maggior parte delle API moderne indica semplicemente alle librerie di sistema quali eventi ti interessano e ti consente di sapere quando accadono.

  3. L’inversione del controllo è un modo pratico per ridurre la duplicazione del codice, e se ti ritrovi a copiare un intero metodo e modificando solo una piccola parte del codice, puoi considerare di affrontarlo con l’inversione del controllo. L’inversione del controllo è resa facile in molti linguaggi attraverso il concetto di delegati, interfacce o anche puntatori di funzioni grezzi.

    Non è appropriato da usare in tutti i casi, perché il stream di un programma può essere più difficile da seguire quando viene scritto in questo modo. È un modo utile per progettare metodi durante la scrittura di una libreria che verrà riutilizzata, ma dovrebbe essere usata con parsimonia nel nucleo del proprio programma a meno che non risolva realmente un problema di duplicazione del codice.

Ma penso che tu debba stare molto attento con questo. Se si abuserà di questo schema, realizzerete un design molto complicato e un codice ancora più complicato.

Come in questo esempio con TextEditor: se hai un solo SpellChecker forse non è veramente necessario usare IoC? A meno che non sia necessario scrivere test unitari o qualcosa del genere …

Ad ogni modo: sii ragionevole. I modelli di progettazione sono buone pratiche ma non la Bibbia da predicare. Non attaccarlo ovunque.

Supponi di essere un object. E tu vai in un ristorante:

Senza IoC : chiedi “mela” e ti viene sempre servita mela quando chiedi di più.

Con IoC : puoi chiedere “frutto”. Puoi ottenere frutti diversi ogni volta che ti viene servito. per esempio, mela, arancia o anguria.

Quindi, ovviamente, IoC è preferito quando ti piacciono le varietà.

IoC / DI per me sta spingendo le dipendenze verso gli oggetti chiamanti. Super semplice.

La risposta non tecnica è la possibilità di sostituire un motore in un’automobile appena prima di accenderlo. Se tutto funziona correttamente (l’interfaccia), sei bravo.

  1. L’inversione del controllo è un modello utilizzato per disaccoppiare componenti e livelli nel sistema. Il modello è implementato attraverso l’iniezione di dipendenze in un componente quando viene costruito. Queste dipendenze vengono solitamente fornite come interfacce per ulteriore disaccoppiamento e per supportare la testabilità. I contenitori IoC / DI come Castle Windsor, Unity sono strumenti (librerie) che possono essere utilizzati per fornire IoC. Questi strumenti forniscono funzionalità estese oltre alla semplice gestione delle dipendenze, tra cui durata, AOP / Intercettazione, politica, ecc.

  2. un. Allevia un componente dall’essere responsabile della gestione delle sue dipendenze.
    b. Offre la possibilità di scambiare implementazioni di dipendenza in ambienti diversi.
    c. Consente a un componente di essere testato attraverso il controllo delle dipendenze.
    d. Fornisce un meccanismo per condividere le risorse attraverso un’applicazione.

  3. un. Critico quando si fa lo sviluppo basato su test. Senza IoC può essere difficile da testare, perché i componenti in prova sono altamente accoppiati al resto del sistema.
    b. Critico nello sviluppo di sistemi modulari. Un sistema modulare è un sistema i cui componenti possono essere sostituiti senza richiedere la ricompilazione.
    c. Critico se vi sono molte preoccupazioni trasversali che devono essere affrontate, in modo frammentario, in un’applicazione aziendale.

Scriverò la mia semplice comprensione di questi due termini:

 For quick understanding just read examples* 

Iniezione delle dipendenze (DI):
Iniezione di dipendenza generalmente significa passare un object su cui il metodo dipende, come parametro per un metodo, piuttosto che avere il metodo per creare l’object dipendente .
In pratica, ciò significa che il metodo non dipende direttamente da una particolare implementazione; qualsiasi implementazione che soddisfi i requisiti può essere passata come parametro.

Con questo oggetti racconterai le loro dipendenze. E la spring lo rende disponibile.
Ciò porta allo sviluppo di applicazioni liberamente accoppiate.

 Quick Example:EMPLOYEE OBJECT WHEN CREATED, IT WILL AUTOMATICALLY CREATE ADDRESS OBJECT (if address is defines as dependency by Employee object) 

Contenitore Inversion of Control (IoC):
Questa è una caratteristica comune dei framework, lo IOC gestisce gli oggetti java
– dall’istanziazione alla distruzione attraverso il suo BeanFactory.
-I componenti Java istanziati dal contenitore IoC sono chiamati bean e il contenitore IoC gestisce l’ambito di un bean, gli eventi del ciclo di vita e tutte le funzionalità AOP per cui è stato configurato e codificato.

QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it .

Implementando Inversion of Control, un utente software / object ottiene più controlli / opzioni sul software / oggetti, invece di essere controllato o con meno opzioni.

L’inversione del controllo come linea guida per la progettazione ha i seguenti scopi:

Esiste un disaccoppiamento nell’esecuzione di un determinato compito dall’implementazione.
Ogni modulo può concentrarsi su ciò per cui è stato progettato.
I moduli non fanno supposizioni su ciò che fanno gli altri sistemi, ma fanno affidamento sui loro contratti.
La sostituzione dei moduli non ha alcun effetto collaterale su altri moduli
Terrò le cose astratte qui, Puoi visitare i seguenti link per la comprensione dettagliata dell’argomento.
Una buona lettura con esempio

Spiegazione dettagliata

Ad esempio, l’attività # 1 è creare un object. Senza il concetto di IOC, il compito n. 1 dovrebbe essere svolto da Programmer. Con il concetto di IOC, l’attività n. 1 dovrebbe essere eseguita dal contenitore.

In breve, il controllo viene invertito dal programmatore al contenitore. Quindi, è chiamato inversione di controllo.

Ho trovato un buon esempio qui .

Rispondere solo alla prima parte. Che cos’è?

Inversion of Control (IoC) significa creare istanze di dipendenze prima e ultima istanza di una class (opzionalmente inserendole tramite il costruttore), invece di creare prima un’istanza della class e poi l’istanza della class che crea istanze di dipendenze. Pertanto, l’inversione del controllo inverte il stream di controllo del programma. Invece del callee che controlla il stream del controllo (durante la creazione delle dipendenze), il chiamante controlla il stream di controllo del programma .

Sono d’accordo con NilObject , ma mi piacerebbe aggiungere a questo:

se ti ritrovi a copiare un intero metodo e modifichi solo una piccola parte del codice, puoi considerare di affrontarlo con l’inversione del controllo

Se ti ritrovi a copiare e incollare il codice, stai quasi sempre facendo qualcosa di sbagliato. Codificato come principio di progettazione Once and Only Once .

Sembra che la cosa più confusa di “IoC” sia l’acronimo e il nome per il quale si basa è che è troppo glamour di un nome – quasi un nome di rumore.

Abbiamo davvero bisogno di un nome con cui descrivere la differenza tra la programmazione procedurale e guidata dagli eventi? OK, se è necessario, ma dobbiamo scegliere un nuovo nome “più grande della vita” che confonde più di quanto risolva?

Diciamo che facciamo qualche incontro in qualche albergo.

Molte persone, molte caraffe d’acqua, tanti bicchieri di plastica.

Quando qualcuno vuole bere, riempie la tazza, beve e butta la tazza sul pavimento.

Dopo l’ora o qualcosa abbiamo un pavimento coperto di bicchieri di plastica e acqua.

Lascia il controllo inverso.

Lo stesso incontro nello stesso posto, ma invece di bicchieri di plastica abbiamo un cameriere con una tazza di vetro (Singleton)

e lei tutto il tempo offre agli ospiti di bere.

Quando qualcuno vuole bere, prende dal bicchiere del cameriere, beve e lo restituisce al cameriere.

Tralasciando la questione dell’igiene, l’ultima forma di controllo del processo di bere è molto più efficace ed economica.

E questo è esattamente ciò che la spring (un altro contenitore IoC, ad esempio: Guice) fa. Invece di lasciare che l’applicazione crei ciò di cui ha bisogno usando una nuova parola chiave (prendendo un bicchiere di plastica), il contenitore Spring IoC offre sempre all’applicazione la stessa istanza (singleton) dell’object necessario (bicchiere d’acqua).

Pensa a te stesso come organizzatore di questo incontro. Hai bisogno del modo di inviare un messaggio all’amministrazione dell’hotel

i membri della riunione avranno bisogno di un bicchiere d’acqua ma non un pezzo di torta.

Esempio:-

 public class MeetingMember { private GlassOfWater glassOfWater; ... public void setGlassOfWater(GlassOfWater glassOfWater){ this.glassOfWater = glassOfWater; } //your glassOfWater object initialized and ready to use... //spring IoC called setGlassOfWater method itself in order to //offer to meetingMember glassOfWater instance } 

Link utili:-

IoC significa invertire la relazione tra il codice e il codice di terze parti (libreria / framework):

  • Nel normale sviluppo di s / w, si scrive il metodo main () e si chiamano i metodi “library”. Hai il controllo 🙂
  • In IoC il “framework” controlla main () e chiama i tuoi metodi. Il quadro è sotto controllo 🙁

DI (Dependency Injection) riguarda il modo in cui il controllo scorre nell’applicazione. L’applicazione desktop tradizionale ha il stream di controllo dall’applicazione (metodo main ()) ad altre chiamate di metodi di libreria, ma con il controllo di stream DI viene invertito, il framework si occupa di avviare l’app, inizializzarla e richiamare i metodi quando richiesto.

Alla fine vinci sempre 🙂

Una spiegazione scritta molto semplice può essere trovata qui

http://binstock.blogspot.in/2008/01/excellent-explanation-of-dependency.html

dice

“Ogni applicazione non banale è composta da due o più classi che collaborano tra loro per eseguire alcune logiche di business, tradizionalmente ogni object è responsabile di ottenere i propri riferimenti agli oggetti con cui collabora (le sue dipendenze). agli oggetti vengono assegnate le loro dipendenze al momento della creazione da parte di un’entity framework esterna che coordina ogni object nel sistema, in altre parole, le dipendenze vengono iniettate negli oggetti. ”

Programmazione del parlato

IoC in termini semplici: è l’uso di Interface come un modo specifico di qualcosa (un campo o un parametro) come un carattere jolly che può essere utilizzato da alcune classi. Permette la riutilizzabilità del codice.

Ad esempio, diciamo che abbiamo due classi: Cane e Gatto . Entrambi condividono le stesse qualità / stati: età, taglia, peso. Quindi, invece di creare una class di servizio chiamata DogService e CatService , posso creare una singola chiamata AnimalService che consente di utilizzare Dog and Cat solo se usano l’interfaccia IAnimal .

Tuttavia, pragmaticamente parlando, ha alcuni arretrati.

a) La maggior parte degli sviluppatori non sa come usarla . Ad esempio, posso creare una class denominata Cliente e posso creare automaticamente (utilizzando gli strumenti dell’IDE) un’interfaccia chiamata ICustomer . Quindi, non è raro trovare una cartella piena di classi e interfacce, non importa se le interfacce saranno riutilizzate o meno. Si chiama BLOATED. Alcune persone potrebbero obiettare che “potrebbe essere in futuro potremmo usarlo”. : – |

b) Ha alcuni limiti. Per esempio, parliamo del caso di Dog and Cat e voglio aggiungere un nuovo servizio (funzionalità) solo per i cani. Let’s say that I want to calculate the number of days that I need to train a dog ( trainDays() ), for cat it’s useless, cats can’t be trained (I’m joking).

b.1) If I add trainDays() to the Service AnimalService then it also works with cats and it’s not valid at all.

b.2) I can add a condition in trainDays() where it evaluates which class is used. But it will break completely the IoC.

b.3) I can create a new class of service called DogService just for the new functionality. But, it will increase the maintainability of the code because we will have two classs of service (with similar functionality) for Dog and it’s bad.

Inversion of Control is a generic principle, while Dependency Injection realises this principle as a design pattern for object graph construction (ie configuration controls how the objects are referencing each other, rather than the object itself controlling how to get the reference to another object).

Looking at Inversion of Control as a design pattern, we need to look at what we are inverting. Dependency Injection inverts control of constructing a graph of objects. If told in layman’s term, inversion of control implies change in flow of control in the program. Per esempio. In traditional standalone app, we have main method, from where the control gets passed to other third party libraries(in case, we have used third party library’s function), but through inversion of control control gets transferred from third party library code to our code, as we are taking the service of third party library. But there are other aspects that need to be inverted within a program – eg invocation of methods and threads to execute the code.

For those interested in more depth on Inversion of Control a paper has been published outlining a more complete picture of Inversion of Control as a design pattern (OfficeFloor: using office patterns to improve software design http://doi.acm.org/10.1145/2739011.2739013 with a free copy available to download from http://www.officefloor.net/mission.html )

What is identified is the following relationship:

Inversion of Control (for methods) = Dependency (state) Injection + Continuation Injection + Thread Injection

I like this explanation: http://joelabrahamsson.com/inversion-of-control-an-introduction-with-examples-in-net/

It start simple and shows code examples as well.

inserisci la descrizione dell'immagine qui

The consumer, X, needs the consumed class, Y, to accomplish something. That’s all good and natural, but does X really need to know that it uses Y?

Isn’t it enough that X knows that it uses something that has the behavior, the methods, properties etc, of Y without knowing who actually implements the behavior?

By extracting an abstract definition of the behavior used by X in Y, illustrated as I below, and letting the consumer X use an instance of that instead of Y it can continue to do what it does without having to know the specifics about Y.

inserisci la descrizione dell'immagine qui

In the illustration above Y implements I and X uses an instance of I. While it’s quite possible that X still uses Y what’s interesting is that X doesn’t know that. It just knows that it uses something that implements I.

Read article for further info and description of benefits such as:

  • X is not dependent on Y anymore
  • More flexible, implementation can be decided in runtime
  • Isolation of code unit, easier testing

I found a very clear example here which explains how the ‘control is inverted’.

Classic code (without Dependency injection)

Here is how a code not using DI will roughly work:

  • Application needs Foo (eg a controller), so:
  • Application creates Foo
  • Application calls Foo
    • Foo needs Bar (eg a service), so:
    • Foo creates Bar
    • Foo calls Bar
      • Bar needs Bim (a service, a repository, …), so:
      • Bar creates Bim
      • Bar does something

Using dependency injection

Here is how a code using DI will roughly work:

  • Application needs Foo, which needs Bar, which needs Bim, so:
  • Application creates Bim
  • Application creates Bar and gives it Bim
  • Application creates Foo and gives it Bar
  • Application calls Foo
    • Foo calls Bar
      • Bar does something

The control of the dependencies is inverted from one being called to the one calling.

What problems does it solve?

Dependency injection makes it easy to swap with the different implementation of the injected classs. While unit testing you can inject a dummy implementation, which makes the testing a lot easier.

Ex: Suppose your application stores the user uploaded file in the Google Drive, with DI your controller code may look like this:

 class SomeController { private $storage; function __construct(StorageServiceInterface $storage) { $this->storage = $storage; } public function myFunction () { return $this->storage->getFile($fileName); } } class GoogleDriveService implements StorageServiceInterface { public function authenticate($user) {} public function putFile($file) {} public function getFile($file) {} } 

When your requirements change say, instead of GoogleDrive you are asked to use the Dropbox. You only need to write a dropbox implementation for the StorageServiceInterface. You don’t have make any changes in the controller as long as Dropbox implementation adheres to the StorageServiceInterface.

While testing you can create the mock for the StorageServiceInterface with the dummy implementation where all the methods return null(or any predefined value as per your testing requirement).

Instead if you had the controller class to construct the storage object with the new keyword like this:

 class SomeController { private $storage; function __construct() { $this->storage = new GoogleDriveService(); } public function myFunction () { return $this->storage->getFile($fileName); } } 

When you want to change with the Dropbox implementation you have to replace all the lines where new GoogleDriveService object is constructed and use the DropboxService. Besides when testing the SomeController class the constructor always expects the GoogleDriveService class and the actual methods of this class are triggered.

When is it appropriate and when not? In my opinion you use DI when you think there are (or there can be) alternative implementations of a class.

Inversion of control is when you go to the grocery store and your wife gives you the list of products to buy.

In programming terms she passed a callback function getProductList() to the function you are executing doShopping() ;

It allows user of the function to define some parts of it making it more flexible.

I understand that the answer has already been given here. But I still think, some basics about the inversion of control have to be discussed here in length for future readers.

Inversion of Control (IoC) has been built on a very simple principle called Hollywood Principle . And it says that,

Don’t call us, we’ll call you

What it means is that don’t go to the Hollywood to fulfill your dream rather if you are worthy then Hollywood will find you and make your dream comes true. Pretty much inverted, huh?

Now when we discuss about the principle of IoC, we use to forget about the Hollywood. For IoC, there has to be three element, a Hollywood, you and a task like to fulfill your dream.

In our programming world, Hollywood represent a generic framework (may be written by you or someone else), you represent the user code you wrote and the task represent the thing you want to accomplish with your code. Now you don’t ever go to trigger your task by yourself, not in IoC! Rather you have designed everything in such that your framework will trigger your task for you. Thus you have built a reusable framework which can make someone a hero or another one a villain. But that framework is always in charge, it knows when to pick someone and that someone only knows what it wants to be.

A real life example would be given here. Suppose, you want to develop a web application. So, you create a framework which will handle all the common things a web application should handle like handling http request, creating application menu, serving pages, managing cookies, triggering events etc.

And then you leave some hooks in your framework where you can put further codes to generate custom menu, pages, cookies or logging some user events etc. On every browser request, your framework will run and executes your custom codes if hooked then serve it back to the browser.

So, the idea is pretty much simple. Rather than creating a user application which will control everything, first you create a reusable framework which will control everything then write your custom codes and hook it to the framework to execute those in time.

Laravel and EJB are examples of such a frameworks.

Riferimento:

https://martinfowler.com/bliki/InversionOfControl.html

https://en.wikipedia.org/wiki/Inversion_of_control

Inversion of control is about transferring control from library to the client. It makes more sense when we talk about a client that injects (passes) a function value (lambda expression) into a higher order function (library function) that controls (changes) the behavior of the library function. A client or framework that injects library dependencies (which carry behavior) into libraries may also be considered IoC

  1. So number 1 above . Cos’è l’inversione del controllo?

  2. Maintenance is the number one thing it solves for me. It guarantees I am using interfaces so that two classs are not intimate with each other.

In using a container like Castle Windsor, it solves maintenance issues even better. Being able to swap out a component that goes to a database for one that uses file based persistence without changing a line of code is awesome (configuration change, you’re done).

And once you get into generics, it gets even better. Imagine having a message publisher that receives records and publishes messages. It doesn’t care what it publishes, but it needs a mapper to take something from a record to a message.

 public class MessagePublisher { public MessagePublisher(IMapper mapper,IRemoteEndpoint endPointToSendTo) { //setup } } 

I wrote it once, but now I can inject many types into this set of code if I publish different types of messages. I can also write mappers that take a record of the same type and map them to different messages. Using DI with Generics has given me the ability to write very little code to accomplish many tasks.

Oh yeah, there are testability concerns, but they are secondary to the benefits of IoC/DI.

I am definitely loving IoC/DI.

3 . It becomes more appropriate the minute you have a medium sized project of somewhat more complexity. I would say it becomes appropriate the minute you start feeling pain.

Creating an object within class is called tight coupling, Spring removes this dependency by following a design pattern(DI/IOC). In which object of class in passed in constructor rather than creating in class. More over we give super class reference variable in constructor to define more general structure.

To understanding the concept, Inversion of Control (IoC) or Dependency Inversion Principle (DIP) involves two activities: abstraction, and inversion. Dependency Injection (DI) is just one of the few of the inversion methods.

To read more about this you can read my blog Here

  1. Che cos’è?

It is a practice where you let the actual behavior come from outside of the boundary (Class in Object Oriented Programming). The boundary entity only knows the abstraction (eg interface, abstract class, delegate in Object Oriented Programming) of it.

  1. Quali problemi risolve?

In term of programming, IoC try to solve monolithic code by making it modular, decoupling various parts of it, and make it unit-testable.

  1. Quando è appropriato e quando no?

It is appropriate most of the time, unless you have situation where you just want monolithic code (eg very simple program)

Using IoC you are not new’ing up your objects. Your IoC container will do that and manage the lifetime of them.

It solves the problem of having to manually change every instantiation of one type of object to another.

It is appropriate when you have functionality that may change in the future or that may be different depending on the environment or configuration used in.