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
Applicare il versioning ai nostri endpoint ASP.NET Core Minimal API
Filtrare e rimuovere gli elementi dalla cache del browser tramite le API JavaScript
Gestire liste di tipi semplici con Entity Framework Core
Eseguire un metodo asincrono dopo il set di una proprietà in Blazor 8
Miglioramenti nell'accessibilità con Angular CDK
Limitare le richieste lato server con l'interactive routing di Blazor 8
Personalizzare l'errore del rate limiting middleware in ASP.NET Core
Gestire errori funzionali tramite exception in ASP.NET Core Web API
Usare una container image come runner di GitHub Actions
Miglioramenti nelle performance di Angular 16
Gestire domini wildcard in Azure Container Apps
Implementare il throttling in ASP.NET Core
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