Ninject Topshelf Microsoft.Owin.Hosting

时间:2014-06-26 17:27:10

标签: ninject owin topshelf

如何利用Topshelf.Ninject并合并OwinNinjectDependencyResolver(来自Ninject.Web.WebApi.OwinHost)?

我可以让它工作但我需要实例化Ninject内核两次(一次用于Topshelf,一次用于我的HttpConfiguration.DependencyResolver。这似乎不是使用Ninject的正确方法。

与此特定设计相关的任何帮助或示例代码都非常有用。

1 个答案:

答案 0 :(得分:5)

所以我有同样的问题,我设法解决了。

关键是:

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

完整的解决方案如下:

  1. 创建一个名为BackgroundProcessor的控制台应用程序解决方案。
  2. 使用NuGet将下面Packages.config列表中列出的软件包添加到解决方案中。
  3. 使用下面的列表为解决方案添加App.config
  4. 将以下提供的每个代码文件添加到解决方案中;我提供了完整的列表,因为代码行对using语句非常敏感,因为解决方案使用的库大量使用扩展方法。
  5. 编译并运行项目。
  6. 点击本地计算机上的网址http://localhost:9000/test来测试解决方案。
  7. <强> 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!");
                }
            }
        }
    }