2013-03-07 5 views
5

Così Inversion Of Control è una descrizione vaga, così Dependency Injection divenne la nuova definizione. Questa è una soluzione molto, molto potente ed è probabilmente altrettanto confusa con qualcuno che non l'ha mai incontrata.I Cinque W di DI, CIO perché sta facendo esplodere il mio cervello

Quindi, nella mia ricerca di non essere un cervo in fari, ho letto. Ho trovato diversi libri fantastici e post online. Ma come tutte le cose meravigliose, più domande sorsero piuttosto che risposte.

Il problema, l'assorbimento di variabili da un progetto sconosciuto da implementare una volta che sono state introdotte nel mio progetto.

La soluzione:

public interface ISiteParameter 
{ 
    Guid CustomerId { get; set; } 
    string FirstName { get; set; } 
    string LastName { get; set; } 
    string Phone { get; set; } 
} 

mio iniettore:

public interface IInjectSiteParameter 
{ 
    void InjectSite(ISiteParameter dependant); 
} 

Poi ho creato questo:

public class SiteContent : IInjectSiteParameter 
{ 
    private ISiteParameter _dependent; 

    #region Interface Member: 
    public void InjectSite(ISiteParameter dependant) 
    { 
     _dependant = dependant; 
    } 
    #endregion 
} 

Poi, per attuare con una condivisa riferimento essere variabili Fed Ho creato una classe da implementare come:

public class SiteParameters : ISiteParameter 
{  
    public Guid Customer Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string Phone { get; set; } 
} 

Ora l'SiteParameters Class sarà referenziato dall'altro progetto; che mi permetterà di chiamare in realtà queste proprietà quando e dove con:

ISiteParameter i = new ISiteParameter(); 
MessageBox.Show(i.Guid + i.FirstName + i.LastName + i.Phone); 

Quella è stata la realizzazione, ma la mia domanda è questa ... Quando faccio posso utilizzare?

  • Constructor iniezione
  • Setter iniezione
  • interfaccia iniezione

Quando desiderate utilizzare uno o l'altro? E per il compito che ho menzionato dovrei aver implementato un compito così difficile da regolare per eventuali modifiche apportate all'altro progetto?

Sono caduto dalla curva nel mio processo di pensiero?

+0

affido la vostra incursione nel DI, anzi è potente. Come hai ottenuto la configurazione non c'è ancora molto vantaggio rispetto al semplice passaggio di valori specifici tramite firma al metodo. Il vero potere si presenterà quando l'istanza di ISiteParameter contiene metodi definiti specifici per il suo comportamento, a parte le altre istanze di ISiteParameter. – KodeKreachor

+0

@KodeKreachor Stavo riflettendo su come implementare alcuni di questi benefici. Ma io sono un vergine DI/IoC. – Greg

+0

Devo sottolineare che stai tentando di istanziare un'interfaccia '.. –

risposta

3

Tirato dal capitolo 4 del Dependency Injection in .NET da Mark Seemann

iniezione Constructor dovrebbe essere la vostra scelta di default per DI. Affronta lo scenario più comune in cui una classe richiede una o più dipendenze. Se la classe dipendente non può assolutamente funzionare senza la dipendenza che la garanzia è preziosa.

L'iniezione di proprietà deve essere utilizzata solo quando la classe che si sta sviluppando ha una buona impostazione locale e si desidera comunque consentire ai chiamanti di fornire implementazioni diverse della dipendenza della classe. L'iniezione di proprietà può anche essere utilizzata nei casi in cui i framework richiedono l'utilizzo di costruttori predefiniti, come le pagine ASP.NET.

L'iniezione del metodo è preferibile quando la dipendenza può variare a seconda della chiamata di ciascun metodo.Questo può essere il caso in cui la dipendenza stessa rappresenta un valore, ma è spesso vista quando il chiamante desidera fornire al consumatore informazioni sul contesto in cui l'operazione viene invocata.

+0

Scenderò più in basso nella tana del coniglio con quella lettura. – Greg

1

Ove possibile, utilizzo i costruttori per passare le dipendenze, invece di iniettare tramite una chiamata di metodo.

Ad esempio:

public interface IWebHost 
{ 
    string DoSomething(string input); 
} 

public class FooManager 
{ 
    private IWebHost _host; 
    public FooManager(IWebHost host) 
    { 
     _host = host; 
    } 

    public void Process() 
    { 
     // do something with _host 
    } 
} 

Ci sono una serie di vantaggi a questo, ma i due che trovo più vantaggioso:

  • mie dipendenze vengono specificate up-front, c'è meno possibilità di uno essere mancato
  • Posso utilizzare un repository di Dependency Injection per eseguire automaticamente la costruzione per me.

Ci sono scenari in cui è impossibile o poco pratico farlo, ma la maggior parte di essi può essere aggirata iniettando una fabbrica che fa la costruzione per me.

Un altro esempio:

public interface IConnection : IDisposable 
{ 
    string DoSomething(string input); 
    // implement IDisposable 
} 

public interface IConnectionFactory 
{ 
    IConnection CreateConnection(); 
} 

public class DerpConnection : IConnection 
{ 
    // implementation 
} 

public class DerpConnectionFactory : IConnectionFactory 
{ 
    // We only return DerpConnections from this factory. 

    IConnection CreateConnection() { return new DerpConnection(); } 
} 

public class BarManager 
{ 
    private IConnectionFactory _connectionFactory; 
    public BarManager(IConnectionFactory connectionFactory) 
    { 
     _connectionFactory = connectionFactory; 
    } 

    public void Manage() 
    { 
     using(var connection = _connectionFactory.CreateConnection()) 
     { 
     // do something here. 
     } 
    } 
} 

Il quadro DI deve solo conoscere il IConnectionFactory in questo esempio, e l'attuazione di fabbrica costruisce direttamente il DerpConnection. Nei test di unità, posso prendere facilmente in giro la fabbrica e la risposta di IConnection.

Scenari in cui ciò non sia possibile, di solito indicano qualche tipo di cross-cutting concern, o la classe è molto più complesso di quello che deve essere (e sta violando SRP)

+0

Grazie, lo esaminerò. – Greg

Problemi correlati