NInject e MVC 3: dovrei utilizzare DependencyResolver anziché l'attributo [Inject]?
-
14-11-2019 - |
Domanda
Recentemente sono passato a MVC 3 e Ninject 2.Nella maggior parte del codice utilizzo l'iniezione del costruttore, ma ci sono alcuni punti in cui ho dovuto utilizzare Inject
attributo.Ninject 2 registra il proprio IDepencyResolver
interfaccia.Non mi piace DependencyResolver
classe di cui fa parte System.Web.Mvc
namespace, perché la sua funzione non è strettamente correlata a MVC, ma ora, quando è lì, posso farlo
public SomeClass
{
public IUserService UserService { get; set; }
public SomeClass()
{
UserService = DependencyResolver.Current.GetService<IUserService>();
invece di
public SomeClass
{
[Inject]
public IUserService UserService { get; set; }
quindi non devo fare riferimento Ninject
spazio dei nomi nelle mie classi.Dovrebbe DependencyResolver
essere usato così?
Soluzione
Utilizzo l'inserimento di proprietà solo per le dipendenze che non sono necessarie per il corretto funzionamento della classe ma che potrebbero aggiungere alcune funzionalità se l'utente le imposta.Un esempio di tale funzionalità è la registrazione.Quindi potresti avere una proprietà che rappresenta un logger in cui l'utente può fornire la propria implementazione e in caso contrario la classe continua a funzionare normalmente ma semplicemente non registra.
Per tutto il resto utilizzo l'iniezione del costruttore.In questo modo indichi al consumatore che questa classe ha una dipendenza richiesta da qualche altro servizio.
Quindi, per rispondere alla tua domanda sull'iniezione immobiliare, avrei semplicemente:
public SomeClass
{
public IUserService UserService { get; set; }
public void SomeMethodWhichDoesntEnforceUserService()
{
if (UserService != null)
{
// Provide some additional functionality
}
}
}
e se la tua classe non può funzionare correttamente senza il servizio utente:
public SomeClass
{
private readonly IUserService _userService;
public SomeClass(IUserService userService)
{
_userService = userService;
}
public void SomeMethodWhichRequiresTheService()
{
_userService.DoSomething();
}
}
Quindi in entrambi i casi nessun riferimento alle specifiche DI.Questo è ciò che riguarda l'Inversione del Controllo.
Altri suggerimenti
La prima domanda che vorrei porre è perché non è possibile eseguire l'iniezione del costruttore di IUserService
in SomeClass
?Potrebbe indicare un problema con il design.
Per evitare riferimenti diretti a DependencyResolver
potresti implementare una qualche forma di astrazione di un Service Locator sul framework DI, ad es. CommonServiceLocator, ma come risposta a questa domanda indica che tali astrazioni non dovrebbero essere necessarie quando si esegue correttamente DI.Dovresti invece modificare il design dell'applicazione.
Credo che la versione ninject.web.mvc per mvc3 ora supporti l'iniezione del costruttore sugli attributi del filtro.L'hai provato?