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
Modificare i metadati nell'head dell'HTML di una Blazor Web App
Migrare una service connection a workload identity federation in Azure DevOps
Gestire i dati con Azure Cosmos DB Data Explorer
Testare l'invio dei messaggi con Event Hubs Data Explorer
Ottimizzare il mapping di liste di tipi semplici con Entity Framework Core
Usare i servizi di Azure OpenAI e ChatGPT in ASP.NET Core con Semantic Kernel
Disabilitare automaticamente un workflow di GitHub (parte 2)
Utilizzare Tailwind CSS all'interno di React: installazione
Usare lo spread operator con i collection initializer in C#
Autenticarsi in modo sicuro su Azure tramite GitHub Actions
Usare il colore CSS per migliorare lo stile della pagina
Implementare l'infinite scroll con QuickGrid in Blazor Server