Nello script della scorsa settimana abbiamo visto come Ninject (o in generale qualsiasi IoC container) porti dei grandi benefici in termini di componibilità e testabilità delle nostre applicazioni. In particolare, abbiamo potuto apprezzare la semplicità nell'integrarlo in ASP.NET MVC 5, per sfruttare la constructor injection sui nostri controller.
Purtroppo, il package Ninject.MVC3 non supporta nativamente ASP.NET Web API; immaginiamo di aver realizzato l'ApiController seguente, analogo a quello visto la scorsa settimana:
public class CustomersApiController : ApiController { private IRepository<Customer> _customers; public CustomersApiController(IRepository<Customer> customers) { _customers = customers; } public List<Customer> Get() { return _customers.Get().ToList(); } }
Se proviamo a invocare il metodo Get, otterremo nuovamente l'errore relativo all'assenza di un costruttore senza parametri.

Per risolvere il problema, dobbiamo creare un DependencyResolver custom che sfrutti l'IKernel di Ninject. Si tratta di una classe che implementa l'interfaccia IDependencyResolver e, nello specifico, i due metodi GetService e GetServices. Un esempio di implementazione può essere il seguente:
public class NinjectDependencyResolver : IDependencyResolver { private IKernel kernel; public NinjectDependencyResolver(IKernel kernel) { this.kernel = kernel; } public IDependencyScope BeginScope() { return this; } public object GetService(Type serviceType) { return kernel.TryGet(serviceType); } public IEnumerable<object> GetServices(Type serviceType) { return kernel.GetAll(serviceType); } public void Dispose() { } }
Tralasciando i metodi BeginScope e Dispose, l'implementazione è per il resto assolutamente banale: si tratta semplicemente di sfruttare il kernel che ci siamo memorizzati sul costruttore per istanziare gli oggetti del tipo richiesto.
Per attivare il nostro NinjectDependencyResolver, non dobbiamo far altro che impostarlo nella configurazione di Web API, per esempio, all'interno della classe NinjectWebCommon:
public static class NinjectWebCommon { // altro codice qui ... private static IKernel CreateKernel() { var kernel = new StandardKernel(); // kernel.Bind<Func<IKernel>>()... GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel); return kernel; } }
A questo punto saremo in grado di utilizzare il CustomersApiController che abbiamo realizzato in precedenza, lasciando a Ninject l'incombenza di istanziare l'IRepository
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Utilizzare la cancellazione logica in Azure Container Registry
Utilizzare l'API del browser fetch
Gestire condizioni complesse in JavaScript
GitHub <3 .NET
Permettere l'append ai file di un Azure Storage immutabile
Migliorare la scalabilità di ASP.NET Core 7 grazie all'output cache
Creare Higher-Order functions in JavaScript
Tracciare gli eventi tramite i DevTools di Chrome
Sfruttare l'output cache di ASP.NET Core 7 con i controller
Aggiungere le issue di più repository in una board in GitHub
Commentare una issue associata ad una pull request tramite un workflow di GitHub