2014-06-26 20 views
2

如何使用Topshelf.Ninject并将OwinNinjectDependencyResolver(来自Ninject.Web.WebApi.OwinHost)?Ninject Topshelf Microsoft.Owin.Hosting

我能得到它的工作,但我需要实例化Ninject内核两次(一次为Topshelf,一次为我HttpConfiguration.DependencyResolver,这似乎并没有被使用Ninject的正确途径。

任何帮助或与此相关的具体设计示例代码将是非常有益

+0

我面对完全一样的问题。 –

回答

5

所以我有这个同样的问题,我设法解决它

这里的关键是:。

  • 不使用[assembly: OwinStartup(...)]属性来引导OWIN。
  • 将Ninject注入到用于配置Topshelf的服务类中的IKernel
  • 使用Microsoft.Owin.Hosting.WebApp类的Start(StartOptions options, Action<Owin.IAppBuilder> startup)方法启动自托管的Web应用程序。
  • 通过启动操作将注入的内核传递给OWIN引导程序。
  • 在调用OWIN启动例程中的appBuilder.UseNinjectMiddleware(() => kernel);而不是appBuilder.UseNinjectMiddleware(CreateKernel);时,使用传入的内核引用。
  • 利润。

完整的解决方案如下:

  1. 创建一个名为BackgroundProcessor一个控制台应用程序的解决方案。
  2. 将下面列出的Packages.config列出的软件包添加到使用NuGet的解决方案中。
  3. 使用下面的清单为解决方案添加App.config
  4. 将下面提供的每个代码文件添加到解决方案;由于代码行对于using声明非常敏感,因此我提供了完整列表,因为解决方案使用的库大量使用扩展方法。
  5. 编译并运行该项目。
  6. 通过在本地计算机上点击URL http://localhost:9000/test来测试解决方案。

Packages.config

<?xml version="1.0" encoding="utf-8"?> 
<packages> 
    <package id="Microsoft.AspNet.WebApi" version="5.0.0" targetFramework="net45" /> 
    <package id="Microsoft.AspNet.WebApi.Client" version="5.0.0" targetFramework="net45" /> 
    <package id="Microsoft.AspNet.WebApi.Core" version="5.0.0" targetFramework="net45" /> 
    <package id="Microsoft.AspNet.WebApi.Owin" version="5.0.0" targetFramework="net45" /> 
    <package id="Microsoft.AspNet.WebApi.WebHost" version="5.0.0" targetFramework="net45" /> 
    <package id="Microsoft.Owin" version="2.1.0" targetFramework="net45" /> 
    <package id="Microsoft.Owin.Host.HttpListener" version="2.1.0" targetFramework="net45" /> 
    <package id="Microsoft.Owin.Hosting" version="2.1.0" targetFramework="net45" /> 
    <package id="Newtonsoft.Json" version="4.5.11" 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.0.0" targetFramework="net45" /> 
    <package id="Ninject.Web.WebApi.OwinHost" version="3.2.1.0" targetFramework="net45" /> 
    <package id="Owin" version="1.0" targetFramework="net45" /> 
    <package id="Topshelf" version="3.1.3" targetFramework="net45" /> 
    <package id="Topshelf.Ninject" version="0.3.0.0" targetFramework="net45" /> 
</packages> 

App.config

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <startup> 
     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> 
    </startup> 
    <runtime> 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <dependentAssembly> 
     <assemblyIdentity name="Topshelf" publicKeyToken="b800c4cfcdeea87b" culture="neutral" /> 
     <bindingRedirect oldVersion="0.0.0.0-3.1.122.0" newVersion="3.1.122.0" /> 
     </dependentAssembly> 
     <dependentAssembly> 
     <assemblyIdentity name="Ninject" publicKeyToken="c7192dc5380945e7" culture="neutral" /> 
     <bindingRedirect oldVersion="0.0.0.0-3.2.0.0" newVersion="3.2.0.0" /> 
     </dependentAssembly> 
     <dependentAssembly> 
     <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" /> 
     <bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" /> 
     </dependentAssembly> 
    </assemblyBinding> 
    </runtime> 
</configuration> 

Program.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Ninject; 
using Topshelf; 
using Topshelf.Ninject; 

namespace BackgroundProcessor 
{ 
    using Modules; 
    using Services; 

    public class Program 
    { 
     public static int Main(string[] args) 
     { 
      var exitCode = HostFactory.Run 
      (
       c => 
       { 
        c.UseNinject(new Module()); 

        c.Service<Service> 
        (
         sc => 
         { 
          sc.ConstructUsingNinject(); 

          sc.WhenStarted((service, hostControl) => service.Start(hostControl)); 
          sc.WhenStopped((service, hostControl) => service.Stop(hostControl)); 
         } 
        ); 

        c.SetServiceName("BackgroundProcessorSvc"); 
        c.SetDisplayName("Background Processor"); 
        c.SetDescription("Processes things in the background"); 

        c.EnablePauseAndContinue(); 
        c.EnableShutdown(); 

        c.StartAutomaticallyDelayed(); 
        c.RunAsLocalSystem(); 
       } 
      ); 

      return (int)exitCode; 
     } 
    } 
} 

Modules\Module.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Ninject.Modules; 

namespace BackgroundProcessor 
{ 
    using Contracts; 
    using Services; 

    namespace Modules 
    { 
     public class Module : NinjectModule 
     { 
      public override void Load() 
      { 
       Bind<IService>().To<Service>(); 
      } 
     } 
    } 
} 

Contracts\IService.cs

using System; 

namespace BackgroundProcessor 
{ 
    namespace Contracts 
    { 
     public interface IService 
     { 
      bool Start(Topshelf.HostControl hostControl); 

      bool Stop(Topshelf.HostControl hostControl); 
     } 
    } 
} 

Services\Service.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Owin.Hosting; 
using Ninject; 
using Topshelf; 

namespace BackgroundProcessor 
{ 
    using Configs; 
    using Contracts; 

    namespace Services 
    { 
     public class Service : IService 
     { 
      private readonly IKernel kernel; 

      public Service(IKernel kernel) 
       : base() 
      { 
       this.kernel = kernel; 
      } 

      protected IKernel Kernel 
      { 
       get 
       { 
        return this.kernel; 
       } 
      } 

      protected IDisposable WebAppHolder 
      { 
       get; 
       set; 
      } 

      protected int Port 
      { 
       get 
       { 
        return 9000; 
       } 
      } 

      public bool Start(HostControl hostControl) 
      { 
       if (WebAppHolder == null) 
       { 
        WebAppHolder = WebApp.Start(new StartOptions { Port = Port }, appBuilder => 
        { 
         new StartupConfig().Configure(appBuilder, Kernel); 
        }); 
       } 

       return true; 
      } 

      public bool Stop(HostControl hostControl) 
      { 
       if (WebAppHolder != null) 
       { 
        WebAppHolder.Dispose(); 
        WebAppHolder = null; 
       } 

       return true; 
      } 
     } 
    } 
} 

Configs\StartupConfig.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Web.Http; 
using Ninject; 
using Ninject.Web.Common.OwinHost; 
using Ninject.Web.WebApi.OwinHost; 
using Owin; 

namespace BackgroundProcessor 
{ 
    namespace Configs 
    { 
     public class StartupConfig 
     { 
      public void Configure(IAppBuilder appBuilder, IKernel kernel) 
      { 
       var config = new HttpConfiguration(); 

       config.MapHttpAttributeRoutes(); 
       config.MapDefinedRoutes(); 

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

Configs\RoutesConfig.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Web; 
using System.Web.Http; 

namespace BackgroundProcessor 
{ 
    namespace Configs 
    { 
     public static class RoutesConfig 
     { 
      public static void MapDefinedRoutes(this HttpConfiguration config) 
      { 
       config.Routes.MapHttpRoute 
       (
        name: "DefaultApi", 
        routeTemplate: "api/{controller}/{id}", 
        defaults: new 
        { 
         id = RouteParameter.Optional 
        } 
       ); 
      } 
     } 
    } 
} 

Controllers\TestController.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Net.Http; 
using System.Text; 
using System.Threading.Tasks; 
using System.Web; 
using System.Web.Http; 

namespace BackgroundProcessor 
{ 
    namespace Controllers 
    { 
     [RoutePrefix("test")] 
     public class TestController : ApiController 
     { 
      [HttpGet] 
      [Route("")] 
      public HttpResponseMessage Index() 
      { 
       return Request.CreateResponse<string>(HttpStatusCode.OK, "Hello world!"); 
      } 
     } 
    } 
} 
+0

奥马尔,感谢您的非常广泛的答复。我仍然面临这个问题,所以我会尝试实施你的解决方案,并让你知道它是如何发生的。 – codemech

+0

这是一个[包含整个解决方案的zip文件]的链接(https://www.dropbox.com/s/e4cx490e5igls2c/BackgroundProcessor.zip)。这可能比手动重新创建整个项目更有帮助。 –

+0

太好了。该zip文件将非常有帮助。 – codemech