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

With over 13 years of professional experience as a .NET developer, I have honed my expertise in various facets of the .NET framework and related technologies. My extensive background includes proficiency in WPF, Web APIs, WCF services, and Windows services, which has enabled me to deliver robust and scalable applications across different domains.

Leave a Reply

Your email address will not be published. Required fields are marked *