web-dev-qa-db-fra.com

Comment utiliser l'amorçage Ninject dans WebApi OwinHost Startup?

Je migre de IIS WebAPI vers OwinHost. En utilisant les dernières versions préliminaires des paquets Nuget, j'ai utilisé avec succès les instructions ici:

https://github.com/ninject/Ninject.Web.Common/wiki/Setting-up-a-OWIN-WebApi-application

Voici un extrait de mon code:

    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();
        config.MapHttpAttributeRoutes();

        app.UseNinjectMiddleware(CreateKernel);
        app.UseNinjectWebApi(config);
    }

    private static StandardKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        kernel.Load(Assembly.GetExecutingAssembly());
        RegisterServices(kernel);
        return kernel;
    }

    private static void RegisterServices(IKernel kernel)
    {
        ...
    }

Mais dans mon code et dans l'exemple de documentation, le noyau Ninject n'est créé qu'après le démarrage. Cependant, j'ai besoin de Ninject DI dans le processus d'enregistrement au démarrage pour l'enregistrement de middleware Cors et OAuth. Avant de migrer vers OwinHost, je pouvais faire quelque chose comme ceci:

public void Configuration(IAppBuilder app)
{
  _bootstrapper = new Bootstrapper();
  _bootstrapper.Initialize(CreateKernel);           

  var config = new HttpConfiguration();
  config.MapHttpAttributeRoutes();

  // USE _boostrapper.Kernel here

  app.UseNinjectMiddleware(CreateKernel);
  app.UseNinjectWebApi(config);
}

Mais en interne, OwinBootstrapper.Execute finira par appeler CreateKernel et bootstrapper.Initialize une seconde fois, avec de graves conséquences.

Quelle est la bonne façon de créer et d'utiliser le noyau ninject dans Startup tout en enregistrant le middleware Ninject/WebAPI?

18
tikinoa

Ajoutez les packages de nuget suivants à votre application:

  1. Package d'installation Microsoft.AspNet.WebApi.Owin
  2. Paquet d'installation Ninject

Si vous utilisez Web api version 5.0.0.0, vous devez également télécharger la classe Ninject Resolver à partir du référentiel pour éviter les problèmes de compatibilité.

Créer une méthode statique qui retourne un objet Kernel

public static class NinjectConfig
{
    public static IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        //Create the bindings
        kernel.Bind<IProductsRepository>().To<ProductRepository>();
        return kernel;
    }
}

Ensuite, vous pouvez utiliser ninject dans votre classe de démarrage

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();
        config.DependencyResolver = new NinjectResolver(NinjectConfig.CreateKernel());

        config.Routes.MapHttpRoute("default", "api/{controller}/{id}", new { id=RouteParameter.Optional });

        app.UseWebApi(config);
    }
}
20
olif

Créez la kernel manuellement puis faites en sorte que UseNinjectMiddleware utilise le même au lieu d'en créer un autre.

public void Configuration(IAppBuilder app)
{
  var kernel = CreateKernel()

  var config = new HttpConfiguration();
  config.MapHttpAttributeRoutes();

  // USE kernel here

  app.UseNinjectMiddleware(() => kernel);
  app.UseNinjectWebApi(config);
}
5
Shago

En plus du message d'Olif:

  1. install-package ninject.extensions.conventions

  2. Dans votre classe de démarrage, ajoutez: using Ninject.Extensions.Conventions;

  3. Au lieu de lier manuellement:

 public static IKernel CreateKernel()
     {
         var kernel = new StandardKernel();
         //Create the bindings
         kernel.Bind<IProductsRepository>().To ProductRepository ();
         return kernel;
     }

Vous pouvez maintenant faire:

kernel.Bind(x =>
                {
                    x.FromThisAssembly()
                    .SelectAllClasses()
                    .BindDefaultInterface();
                });

Cela examinera votre Assemblée et fera automatiquement la reliure.

1
Virgar Poulsen