Today I am going to show you how to host a WCF service in a managed environment such as windows service. Let us see how to achieve this through C#.
Here, I will first show you how to create a simple windows service and then how to host a WCF service in it.
I will also show you how to pass the external messages received on this service, to a host. I am going to use a singleton pattern to avoid the race condition while receiving messages concurrently.
- Create a “Console Application” project named as “SelfHostService” using installed templates in Visual Studio
- Delete Program.cs file from project
- Add a new class named as SelfHostService.cs
- Click Add Reference menu to open a Add Reference Dialog Box
- Select
System.ServiceProcessnamespace to refer ServiceBaseclass resides in this newly added namespace, which is required to create a service application. DeriveSerivceBaseclass inSelfHostServiceclass- Also add a reference to
System.ServiceModelnamespace - Now let us put some code in
SelfHostServiceclass - In above code I have created a public property named
Instanceto provide a single instance ofSelfHostServiceclass - Now let us define a service contract
IMessageListener - We will have to override
OnStart()andOnStop()methods ofServiceBaseclass. These methods contains instructions to follow when service starts and stops respectively. Let us write a code for these methods DoWorkmethod is a task assigned to a timer which has been initialized inOnStart()method. After every interval elapses, this method will get executed. So one can write any code which is to be performed repetitively by a window service.- I will add a method to accept requests, received by
MessageListenerService - Now we will implement
IMessageListenerinMessageListenerService - We will have to configure the services’ base address, binding and contracts
public class SelfHostService : ServiceBase
{
public ServiceHost serviceHost = null;
private bool startProcessing;
private static SelfHostService instance = null;
private static readonly object padlock = new object();
//a private constructor
SelfHostService()
{
ServiceName = "Self Hosted Service";
}
//public static property to access the instance of the SelfHostService class
public static SelfHostService Instance
{
get
{
lock (padlock)
{
if (instance == null)
instance = new SelfHostService();
return instance;
}
}
}
}
namespace SelfHostService
{
public interface IMessageListener
{
bool AcceptMessages(string messsage);
}
}
protected override void OnStart(string[] args)
{
if (serviceHost != null)
serviceHost.Close();
serviceHost = new ServiceHost(typeof(MessageListenerService));
serviceHost.Open();
var timer = new Timer();
timer.Interval = 60000;
timer.Elapsed += new ElapsedEventHandler(DoWork);
timer.Start();
}
protected override void OnStop()
{
if (serviceHost != null)
{
serviceHost.Close();
serviceHost = null;
}
}
private void DoWork(object sender, ElapsedEventArgs e)
{
//Add code to do the intended work
}
public bool AcceptExternalMessages(string message)
{
if (string.IsNullOrEmpty(message))
return false;
else
return true;
}
public class MessageListenerService : IMessageListener
{
public bool AcceptMessages(string message)
{
//Notify message to windows service
return SelfHostService.Instance.AcceptExternalMessages(message);
}
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="SelfHostService.MessageListenerService" behaviorConfiguration="ServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8082/SelfHostService/Service"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="SelfHostService.IMessageListener" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior" >
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
In my next post I will write about how to install this service using InstallUtil.exe
Note: This code post is written in C# 6.0 in Visual Studio 2015