如何在WebApi OwinHost启动中使用Ninject引导程序?

19

我正在从IIS WebAPI迁移到OwinHost。利用最新的nuget包预发布版本,我成功地使用了这里的说明:

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

以下是我的示例代码:

    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)
    {
        ...
    }

但是在我的代码和文档示例中,Ninject内核是在启动之后才被创建的。然而,在启动注册Cors和OAuth中间件的过程中需要使用Ninject DI。在迁移到OwinHost之前,我可以这样做:

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);
}

但实际上,OwinBootstrapper.Execute会导致CreateKernel和bootstrapper.Initialize第二次调用,造成不良后果。

如何正确地在启动过程中创建和使用Ninject内核,并仍然注册Ninject/WebAPI中间件?


我也遇到了一些困难,发现这个SO Q&A很有帮助:https://dev59.com/w2Af5IYBdhLWcg3wsUbT - JasonCoder
3个回答

21

将以下 nuget-packages 添加到您的应用程序中:

  1. Install-Package Microsoft.AspNet.WebApi.Owin
  2. Install-Package Ninject

如果您正在使用 Web API 版本 5.0.0.0,还需要从存储库中下载 Ninject Resolver 类,以避免兼容性问题。

创建一个返回 Kernel 对象的静态方法。

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

然后您可以在启动类中使用Ninject。

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);
    }
}

1
我尝试了很多组合来让我的Owin + WebApi工作。幸亏有你,我终于解决了它。你的回答中唯一缺少的包是Ninjec.Web.Common。非常感谢。 - Ricardo Huertas
感谢您的优秀回答!我已经寻找很久了! - jao
config.DependencyResolver = new NinjectResolver(new Ninject.Web.Common.Bootstrapper().Kernel); 这是唯一对我有效的解决方案!尝试使用 app.UseNinjectMiddleware 和 app.UseNinjectWebApi 时,无论我做什么都会出现“InvalidOperationException: Sequence contains no elements”的错误。此外,我只需安装 WebApiContrib.IoC.Ninject 的 NuGet 包,而不是“从 repo 下载 Ninject Resolver 类”。 - CrazyPyro
这对我起作用了,我只是在 statup.cs 的 Configuration 函数的最后调用了 Resolver。config.DependencyResolver = new NinjectHttpDependencyResolver(new Ninject.Web.Common.Bootstrapper().Kernel);NinjectHttpDependencyResolver 是我的解析器类。 - Sai Kumar

5
手动创建内核,然后让UseNinjectMiddleware使用同一个内核而不是创建另一个。
public void Configuration(IAppBuilder app)
{
  var kernel = CreateKernel()

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

  // USE kernel here

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

0
除了Olif的帖子外:
  1. 安装包ninject.extensions.conventions

  2. 在启动类中添加:using Ninject.Extensions.Conventions;

  3. 不要手动绑定,而是使用:

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

您现在可以做:

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

这将浏览您的程序集,并自动进行绑定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接