2014-06-26 1 views
2

Comment puis-je utiliser Topshelf.Ninject et incorporer OwinNinjectDependencyResolver (à partir de Ninject.Web.WebApi.OwinHost)?Ninject Topshelf Microsoft.Owin.Hosting

Je peux le faire fonctionner mais je dois instancier le noyau Ninject deux fois (une fois pour Topshelf et une fois pour mon HttpConfiguration.DependencyResolver. Cela ne semble pas être la bonne façon d'utiliser Ninject.

Toute aide ou un code d'exemple lié à cette conception spécifique serait très utile

+0

je suis confronté à la même question. –

Répondre

5

donc j'ai eu ce même problème et je réussi à le résoudre

La clé est de:..

  • N'utilisez pas l'attribut [assembly: OwinStartup(...)] pour amorcer OWIN.
  • Injectez un IKernel en utilisant Ninject dans la classe de service utilisée pour configurer Topshelf.
  • Utilisez la méthode Start(StartOptions options, Action<Owin.IAppBuilder> startup) de la classe Microsoft.Owin.Hosting.WebApp pour démarrer l'application Web auto-hébergée.
  • Transmettez le noyau injecté à la routine bootstrap OWIN via l'action de démarrage.
  • Utilisez la référence transmise au noyau dans l'appel à appBuilder.UseNinjectMiddleware(() => kernel); dans la routine de démarrage OWIN, plutôt que appBuilder.UseNinjectMiddleware(CreateKernel);.
  • Profit.

La solution complète est la suivante:

  1. Créer une solution d'application de la console appelée BackgroundProcessor.
  2. Ajoutez les packages répertoriés dans la liste Packages.config ci-dessous à la solution en utilisant NuGet. Ajoutez un App.config à la solution en utilisant la liste ci-dessous.
  3. Ajoutez chacun des fichiers de code fournis ci-dessous à la solution; J'ai fourni les listes complètes en raison des lignes de code sont assez sensibles aux déclarations using en raison de l'utilisation intensive des méthodes d'extension par les bibliothèques utilisées par la solution.
  4. Compilez et exécutez le projet.
  5. Testez la solution en tapant l'URL sur votre ordinateur local.

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

Umar, merci pour la réponse très complète. Je suis toujours confronté à ce problème, donc je vais essayer de mettre en œuvre votre solution et vous laisser savoir comment cela s'est passé. – codemech

+0

Voici un lien vers [un fichier zip contenant la solution complète] (https://www.dropbox.com/s/e4cx490e5igls2c/BackgroundProcessor.zip). Cela peut être plus utile que de recréer manuellement l'ensemble du projet. –

+0

Génial. Le fichier zip sera très utile. – codemech