使用 Ninject OWINHost 的 OWIN 自托管应用程序是不是需要 system.web?

Posted

技术标签:

【中文标题】使用 Ninject OWINHost 的 OWIN 自托管应用程序是不是需要 system.web?【英文标题】:Should OWIN self host app using Ninject OWINHost need system.web?使用 Ninject OWINHost 的 OWIN 自托管应用程序是否需要 system.web? 【发布时间】:2014-10-30 14:13:15 【问题描述】:

我正在尝试使用带有 Ninject 的 OWIN 自托管 WebAPI 创建 Windows 服务。我让它工作,但我必须添加对 system.web 的引用,这似乎是错误的。如果没有对 system.web 的引用,我得到了这些编译错误:

“System.Web.Routing.RouteCollection”类型定义在 未引用的程序集。您必须添加对程序集的引用 'System.Web,版本=4.0.0.0,文化=中性, PublicKeyToken=b03f5f7f11d50a3a'。

“System.Web.Routing.Route”类型是在一个程序集中定义的,该程序集是 未参考。您必须添加对程序集 'System.Web, 版本=4.0.0.0,文化=中性,PublicKeyToken=b03f5f7f11d50a3a'。

根据本文添加Ninject后出现错误 Setting up a OWIN WebApi application

我还必须将 Microsoft.Owin 限制为 2.1.0 版才能使 Ninject 正常工作。在服务启动期间,Ninject 正在寻找 Owin 2.1.0。如果您在 Microsoft.Owin 上获得最新版本,它将滚动到 3.0。

我使用的三个主要 NuGet 包是:

Microsoft.AspNet.WebApi.OwinSelfHost

Ninject.Web.Common.OwinHost

Ninject.Web.WebApi.OwinHost

这是我所有的包(注意 Microsoft.Owin 上的限制)

  <package id="Microsoft.AspNet.WebApi" version="5.2.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.Owin" version="5.2.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.OwinSelfHost" version="5.2.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.2" targetFramework="net45" />
  <package id="Microsoft.Owin" version="2.1.0" targetFramework="net45" allowedVersions="(,2.1]" />
  <package id="Microsoft.Owin.Host.HttpListener" version="3.0.0" targetFramework="net45" />
  <package id="Microsoft.Owin.Hosting" version="2.0.2" targetFramework="net45" />
  <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net45" />
  <package id="Ninject" version="3.2.2.0" targetFramework="net45" />
  <package id="Ninject.Extensions.ContextPreservation" version="3.2.0.0" targetFramework="net45" />
  <package id="Ninject.Extensions.NamedScope" version="3.2.0.0" targetFramework="net45" />
  <package id="Ninject.Web.Common" version="3.2.2.0" targetFramework="net45" />
  <package id="Ninject.Web.Common.OwinHost" version="3.2.2.0" targetFramework="net45" />
  <package id="Ninject.Web.WebApi" version="3.2.1.0" targetFramework="net45" />
  <package id="Ninject.Web.WebApi.OwinHost" version="3.2.1.0" targetFramework="net45" />
  <package id="Owin" version="1.0" targetFramework="net45" />

这是windows服务的Program.cs的样子

using Microsoft.Owin.Hosting;
using Ninject;
using Ninject.Web.Common.OwinHost;
using Ninject.Web.WebApi.OwinHost;
using Owin;
using System.Reflection;
using System.ServiceProcess;
using System.Web.Http;


namespace ServiceExample

    static class Program
    
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main()
        
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
             
                new Service1() 
            ;


            using (WebApp.Start<Startup>("http://localhost:12345"))
            
                ServiceBase.Run(ServicesToRun);  
            
        



        public class Startup
        
            public void Configuration(IAppBuilder app)
            
                ConfigureWebAPI(app);

            

            private void ConfigureWebAPI(IAppBuilder app)
            
                var config = new HttpConfiguration();
                config.Routes.MapHttpRoute(
                    "DefaultApi",
                    "api/controller/id",
                    new id = RouteParameter.Optional);

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


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

【问题讨论】:

【参考方案1】:

我遇到了和你一样的问题,但是没有使用 Ninject OwinHost,而且我确实认为问题不在于 Ninject 而是路由。

问题是这段代码:

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

使用 System.Web.Routing,它包含在 System.Web 命名空间 (Check here) 中。

因此,我发现的替代方法是使用带有属性的生根。所以你可以用这个替换上面的代码:

// Web API routes
config.MapHttpAttributeRoutes();

如果不熟悉,请查看this tutorial。

使用这种方法,您可以删除项目的 System.Web 引用。

【讨论】:

最初我有“app.UseWebApi(config)”所以“Routes.MapHttpRoute”部分就在那里,它在没有 System.Web 的情况下解决了。但是通过添加 Ninject,需要 System.Web。我需要 Ninject 进行依赖注入,使用 MapHttpAttributesRoutes() 如何启动 Ninject? 这是一个很好的实用解决方法,但我有点困惑为什么调用config.Routes.MapHttpRoute 需要引用System.Web。调用中涉及的所有类型(IHttpRouteHttpRouteCollectionRouteParameter)都没有在该程序集中声明,它们都来自System.Web.Http.Routing。并且包含HttpCollectionSystem.Web.Http 程序集不依赖于System.Web。你能解释一下这种依赖是如何产生的吗?【参考方案2】:

尝试从引用中删除System.Web.Http.WebHost.dll


当我想将 API 项目作为类库和单独的宿主项目(使用控制台和其他 IIS)时,我遇到了同样的问题,如 this great blog post 中所述

问题在于,当我执行Install-Package Microsoft.AspNet.WebApi 来安装ASP.NET Web API 时,它还添加了对System.Web.Http.WebHost.dll 的引用,结果packages.json 是:

<packages>
  <package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net452" />
  <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net452" />
</packages>

所以解决方案是删除对System.Web.Http.WebHost.dll 的引用,并从packages.json 中删除Microsoft.AspNet.WebApiMicrosoft.AspNet.WebApi.WebHost,这样当有些人会执行nuget 恢复/重新安装时它不会再次安装:

<packages>
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" />
  <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net452" />
</packages>

这是我来自工作类库ASP.NET Web API项目的packages.json

<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net452" />  
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net452" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net452" />
<package id="Owin" version="1.0" targetFramework="net452" />

【讨论】:

除了你列出的那些之外,我还需要这 3 个来使我的工作(.NET 4.5.1)作为 Windows 服务:“Microsoft.AspNet.WebApi.OwinSelfHost”“Microsoft.Owin .Host.HttpListener" "Microsoft.Owin.Hosting" 添加 Ninject(NUGet 包之一)似乎正在添加似乎打破这一点的参考!简单的解决方案是删除该引用! 添加到上述内容:手动添加对 system.web 的引用似乎也使错误消失并且目前采用这种方法而不是删除对 System.Web.Http.WebHost 的引用(目前不完全清楚该引用是否多余)。 太棒了,你成就了我的一天!

以上是关于使用 Ninject OWINHost 的 OWIN 自托管应用程序是不是需要 system.web?的主要内容,如果未能解决你的问题,请参考以下文章

OwinHost

orace owi??????

使用 Ninject

Ninject 在使用 NinjectHttpModule 时创建一个额外的实例

Ninject之旅之七:Ninject依赖注入

在构造函数中使用带有附加参数的 Ninject 创建实例