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
Eseguire una query su SQL Azure tramite un workflow di GitHub
Utilizzare i primary constructor in C#
Usare il versioning con i controller di ASP.NET Core Web API
Gestire domini wildcard in Azure Container Apps
Effettuare il binding di date in Blazor
Personalizzare l'errore del rate limiting middleware in ASP.NET Core
Generare file PDF da Blazor WebAssembly con iText
Utilizzare la libreria Benchmark.NET per misurare le performance
Usare Refit e Polly in Blazor per creare client affidabili e fortemente tipizzati
Effettuare il deploy di immagini solo da container registry approvati in Kubernetes
Hosting di componenti WebAssembly in un'applicazione Blazor static
Utilizzare database e servizi con gli add-on di Container App
I più letti di oggi
- Riordinare le righe di una GridView di ASP.NET con jQuery
- Creazione di un alarm con suono personalizzato con Windows Phone 7.1
- Utilizzare la session affinity con Azure Container Apps
- Blue-green deployment con Azure Web App e DevOps
- Ed infine anche il calendario :)
- Configurare la diagnostica di Azure attraverso Visual Studio
- Recuperare la data di creazione di un tag tramite una pipeline YAML di Azure DevOps
- Microsoft Security Bulletin MS05-002
- .NET Core e dispositivi IoT
- Eseguire attività pianificate con Azure Container Jobs