2016-03-08 21 views
5

Utilizzo Microsoft Unity come contenitore IoC. Ho un certo numero di classi di estensione che aggiunge metodi utili per la mia attività oggetti Questo è il tipo di codice che usiamo oggi:Iniezione di dipendenza per classi di estensione?

public static class BusinessObjectExtensions 
{ 
    public static bool CanDoStuff(this BusinessObject obj) 
    { 
     var repository = BusinessHost.Resolver.Resolve<IRepository>(); 
     var args = new EArgument { Name = obj.Name }; 
     return repository.AMethod(obj.UserName, args); 
    } 
} 

Esiste un modo migliore per gestire l'iniezione di dipendenza per le classi di estensione?

+0

credo, non mostrando avendo alcun obbligo di essere un'estensione method' '.. tanti oggetti di dipendenza sono loro – Moumit

risposta

2

Si dovrebbe in effetti tentare di evitare extensionmethods a meno che non lavorino solo su dati interni (proprietà nella classe stessa) o semplici tipi di dati forniti nel metodo. Non dovresti parlare ad altre dipendenze nei tuoi metodi di estensione. Se si segue questa regola, non è necessario inserire classi di estensione con il proprio IoC.

+1

Questo è un buon punto. Forse dovrei creare invece una classe di gestione ... – Leonard

4

Il modo predefinito di Iniezione di dipendenza per Iniezione costruttore non è possibile per le classi statiche. Sarebbe possibile usare Parameter Injection come sotto, tuttavia non è un modo molto pulito.

public static class BusinessObjectExtensions 
{ 
    public static bool CanDoStuff(this BusinessObject obj, IRepository repository) 
    { 
     var args = new EArgument { Name = obj.Name }; 
     return repository.AMethod(obj.UserName, args); 
    } 
} 
1

Perché dovresti farlo?

Questo solleva l'accoppiamento nella tua applicazione sul tetto e può essere molto confuso perché i tuoi compagni di squadra utilizzino il metodo di estensione (dovranno tenere a mente di iniettare il repository ogni volta che viene usato il metodo).

Invece, creare una classe separata e utilizzare l'iniezione del costruttore per iniettare l'istanza IRepository:

public class StuffExecuter  
{ 
    private readonly IRepository _repository; 

    public StuffExecuter(IRepository repository) 
    { 
     _repository = repository; 
    } 

    public bool CanExecute(BusinessObject obj) 
    { 
     _repository.Add(obj.UserName, new EArgument 
     { 
      Name = obj.Name 
     }); 
    } 
} 
+0

Questo è il modo in cui lo facciamo in base alla progettazione, ma l'esempio sopra è stato preso da un caso d'uso davvero specifico, se non del tutto isolato, in cui credevamo nella praticità di agganciare la funzionalità avevamo bisogno del nostro oggetto aziendale. Col senno di poi, non è stata una buona idea, quindi la sposterò altrove. Grazie! – Leonard