Sfruttare Ninject con ASP.NET Web API

di Marco De Sanctis, in ASP.NET Web API,

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 richiesto in base alla sua configurazione.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi