La semplice parametrizzazione di una dipendenza soddisfa i requisiti di Inversion of Control?

1

Quando trovo una dipendenza concreta all'interno di un metodo di estensione, ho tentato di rimuovere la dipendenza (concreta) parametrizzandola in questo modo

// original implementation
public static List<Address> GetDuplicate(this Address address)
{
    var repository = new AddressRepository();
    return repository.FindAddress(address.Street, address.Town);
}

// 'Fixed' implementation using 'parameter injection'
public static List<Address> GetDuplicate(this Address address, IAddressRepository repository = null)
{
    repository = repository ?? new AddressRepository();
    return repository.FindAddress(address.Street, address.Town);
}

La mia idea era che ciò avrebbe invertito il controllo della classe collaborante, AddressRepository, facendo in modo che potesse essere passato dal codice usando il metodo.

Ad ogni modo, quando un collega ha visto questo, ha affermato che il codice faceva ancora affidamento su un'implementazione concreta e non utilizzava il CIO. Anche se posso vedere che ci sono alcuni aspetti negativi del codice, non sono sicuro di essere d'accordo sul fatto che non è Inversion of Control dal momento che

  1. Il codice dipende da un'astrazione (IAddressRepository)
  2. Il codice chiamante può fornire un'implementazione diversa.

Quale principio viene violato rispetto al CIO? Quale parte del codice in particolare viola questo principio? In poche parole, l'iniezione di parametri è in realtà una cosa?

    
posta jhsowter 22.02.2015 - 12:54
fonte

1 risposta

2

...does the parameterisation of the dependency meet the requirements for "inversion of control"?

No. È solo un'iniezione delle dipendenze.

Osserva con attenzione la definizione di Wikipedia per Inversion of Control :

Inversion of Control (IoC) describes a design in which custom-written portions of a computer program receive the flow of control from a generic, reusable library [or framework].

In traditional programming, the custom code that expresses the purpose of the program calls into reusable libraries to take care of generic tasks, but with inversion of control, it is the reusable code [the library or framework] that calls into the custom, or task-specific, code.

In altre parole, Inversion of Control è caratterizzato dal Principio di Hollywood : Non chiamarci, ti chiameremo.

Posso pensare ad almeno due modi in cui l'Inversion of Control può verificarsi nell'uso quotidiano. Un modo è facendo uso del modello di sottoscrizione. Nelle UI basate sugli eventi, non chiamiamo la struttura dell'interfaccia utente quando un utente fa clic su un pulsante. Piuttosto, ci iscriviamo ad un evento Click e il framework UI ci chiama:

// Subscribe to Click event.
this.button1.Click += new System.EventHandler(this.button1_Click);

// Handler for click event
private void button1_Click(object sender, MyEventArgs e)
{
    // Do something when user clicks button
}

Un altro esempio di Inversion of Control è metodi di ordinamento che fanno uso di un comparatore per determinare il comportamento dell'ordinamento con diversi tipi di dati. La documentazione MSDN per il metodo Linq OrderBy fornisce un buon esempio di questo.

Per prima cosa, creiamo un "comparatore". Un comparatore è una classe che soddisfa l' interfaccia di IComparer :

public class IntegerComparer : IComparer<int>
{
    public int Compare(int i1, int i2)
    {
        return i1 - i2;
    }
}

Dato un array non ordinato di:

string[] unsortedArray = { "three", "six", "nine", "twelve", "fifteen", "eighteen" };

Possiamo quindi utilizzare il comparatore per ordinare l'array in base al numero di caratteri in ciascuna stringa:

sortedArray = unsortedArray.OrderBy(a => a.Length, new IntegerComparer());

che produce il risultato:

six
nine
three
twelve
fifteen
eighteen

Ancora una volta, abbiamo controllo invertito relegando il comportamento generico al framework e avendo il framework chiama il tuo codice personalizzato per ottenere un comportamento specifico.

Ulteriori letture

Inversion of Control (Martin Fowler's Bliki)

    
risposta data 22.02.2015 - 19:49
fonte