How can I utilize Topshelf.Ninject and incorporate OwinNinjectDependencyResolver (from Ninject.Web.WebApi.OwinHost)?
I can get it to work but I need to instantiate the Ninject kernel twice (once for Topshelf and once for my HttpConfiguration.DependencyResolver. This does not seem to be the right way to use Ninject.
Any help or example code related to this specific design would be very helpful.
So I had this same problem and I managed to solve it.
The key to this is to:
[assembly: OwinStartup(...)]
attribute to bootstrap OWIN.IKernel
using Ninject into the service class being used to configure Topshelf.Start(StartOptions options, Action<Owin.IAppBuilder> startup)
method of the Microsoft.Owin.Hosting.WebApp
class to start the self-hosted web-app.appBuilder.UseNinjectMiddleware(() => kernel);
in the OWIN startup routine, rather than appBuilder.UseNinjectMiddleware(CreateKernel);
.The complete solution is as follows:
Packages.config
listing below to the solution using NuGet.App.config
to the solution using the listing below.using
statements because of heavy use of extension methods by the libraries utilized by the solution.http://localhost:9000/test
on your local machine.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!");
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With