How to self host a WCF service in a windows service

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.

  1. Create a “Console Application” project named as “SelfHostService” using installed templates in Visual Studio
  2. Delete Program.cs file from project
  3. Add a new class named as SelfHostService.cs
  4. Click Add Reference menu to open a Add Reference Dialog Box
  5. Select System.ServiceProcess namespace to refer
  6. ServiceBase class resides in this newly added namespace, which is required to create a service application. Derive SerivceBase class in SelfHostService class
  7. Also add a reference to System.ServiceModel namespace
  8. Now let us put some code in SelfHostService class
  9.     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;
                    }
                }
            }
        }
    
  10. In above code I have created a public property named Instance to provide a single instance of SelfHostService class
  11. Now let us define a service contract IMessageListener
  12. namespace SelfHostService
    {
        public interface IMessageListener
        {
            bool AcceptMessages(string messsage);
        }
    }
    
  13. We will have to override OnStart() and OnStop() methods of ServiceBase class. These methods contains instructions to follow when service starts and stops respectively. Let us write a code for these methods
  14.         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;
                }
            }
    
  15. DoWork method is a task assigned to a timer which has been initialized in OnStart() 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.
  16.         private void DoWork(object sender, ElapsedEventArgs e)
            {
                //Add code to do the intended work
            }
    
  17. I will add a method to accept requests, received by MessageListenerService
  18.         public bool AcceptExternalMessages(string message)
            {
                if (string.IsNullOrEmpty(message))
                    return false;
                else
                    return true;
            }
    
  19. Now we will implement IMessageListener in MessageListenerService
  20.     public class MessageListenerService : IMessageListener
        {
            public bool AcceptMessages(string message)
            {
                //Notify message to windows service
                return SelfHostService.Instance.AcceptExternalMessages(message);
            }
        }
    
  21. We will have to configure the services’ base address, binding and contracts
  22. <?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

About sagar

A web and desktop application developer.

Leave a Reply

Your email address will not be published.