This is a simple example of a windows backend service which hosts a Web Api 2 service. The application is deployed using WiX. The application can then be used as a backend for a simple game with different UIs, for example an android App, MVC 5 web application, or an WPF UI application.
The application uses the nuget package Unity.SelfHostWebApiOwin.
Code for this example can be found here: https://github.com/damienbod/AnimalMarketEngine
The solution has 3 different projects:
- AnimalMarketEngine: Implements the engine logic. The Wep Api 2 service is also implemented here. If it was a more complicated application, I would separate the 2 layers.
- AnimalMarketService: Windows service used to host the Web Api 2 host.
- SetupAnimalMarketService: WiX installer project for the web service.
AnimalMarketEngine Project
This is just a simple empty web project with the Nuget package Unity.SelfHostWebApiOwin added to it. The project uses Unity 3 as an IoC.
The Startup class provides the start and stop methods for the windows service:
public static void StartServer() { string baseAddress = "http://localhost:8081/"; var startup = _container.Resolve<Startup>(); webApplication = WebApp.Start(baseAddress, startup.Configuration); } public static void StopServer() { webApplication.Dispose(); }
The Startup.Configuration method provides the Web Api 2 start and configuration logic.
public void Configuration(IAppBuilder appBuilder) { // Configure Web API for self-host. var config = new HttpConfiguration(); // Add Unity DependencyResolver config.DependencyResolver = new UnityDependencyResolver(UnityHelpers.GetConfiguredContainer()); // Add Unity filters provider RegisterFilterProviders(config); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); appBuilder.UseWebApi(config); }
In the service project, the StartServer and StopServer methods can then be used:
/// <summary> /// OnStart(): Put startup code here /// - Start threads, get inital data, etc. /// </summary> /// <param name="args"></param> protected override void OnStart(string[] args) { Startup.StartServer(); base.OnStart(args); } /// <summary> /// OnStop(): Put your stop code here /// - Stop threads, set final data, etc. /// </summary> protected override void OnStop() { Startup.StopServer(); base.OnStop(); }
The WiX project uses harvest and the whole application can be deployed as an msi installer.
When configuring the WiX wxs project, be careful to use the same Windows Service name defined in your service project in the ServiceInstall Name attribute.
<Component Id='AnimalMarketServiceRegisterComponent' Guid='ABB394C2-21A1-4132-AB7D-95CBBABE5B00' Directory='INSTALLDIR_AnimalMarketService' Feature='ProductFeature' DiskId='1'> <File Id="AnimalMarketServiceExe" Name="AnimalMarketService.exe" Source="..\AnimalMarketService\bin\Release\AnimalMarketService.exe" KeyPath="yes" DiskId="1"/> <ServiceInstall Id='AnimalMarketServiceInstall' Name='AnimalMarketWindowsService' Description='Animal Market service damienbod' ErrorControl='normal' Start='auto' Type='ownProcess' Vital='yes' /> <ServiceControl Id='AnimalMarketServiceInstall' Name='AnimalMarketWindowsService' Start='install' Remove='uninstall' Wait='yes' /> <CreateFolder /> </Component>
Fiddler can then be used to debug your Web Api 2 service.
Links
First of all, I would like to say thank you so much to your post. It is all I was looking for few days ago about how to make a Web API host on Window Service. I cannot make your source code work. I have a problem when I try to start service after installing it successfully. And when I try to run “AnimalMarketEngine” project, I got a error. I’ve taken a picture of the error and uploaded at the link http://pbrd.co/Qy1uRB. Please give me a favour to get overcome this problem. Thank you so much again.
Hi thanks for your comment.
I think your missing the Owin Nuget packages in the start project. If not you need to change the OWIN startup. I try out the code and see if it works with me.
you require
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=”Owin” version=”1.0″ targetFramework=”net45″
Hope this helps, I’ll add this later to the post.
greetings Damien
I’ve fixed it.
After I updated the Web API packages, the startup class required
[assembly: OwinStartup(typeof(Unity.SelfHostWebApiOwin.Startup))]
Latest version on github works.
Thanks for this info
greetings Damien