Self consuming WCF service

It’s easy to create a self consuming WCF service, also can simplify the architecture.

Start a new project with Windows Service project template.
Screenshot (92)
Add the installers to the service. It creates a serviceProcessInstaller1 and serviceIstaller1 objects. You can rename them, if you want. In serviceInstaller1 you can give some meaningful description and name for the service. At the serviceProcessInstaller1 you can set the Account for the service.
Screenshot (93)

Now, lest do the business…
Reference System.Runtime.Serialization.dll (you may need it) and System.ServiceModel.dll.
Add a new interface, in the example I use ILearn, and create the service contract. In basic example you need only

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;

namespace SelfConsumingWcf
{
    [ServiceContract]
    interface ILearn
    {
        [FaultContract(typeof(ErrorInfo))]
        [OperationContract]
        void Add (int incr);

        [OperationContract]
        int GetValue ();
    }

    [DataContract]
    public class ErrorInfo
    {
        public string ErrorMessage { get; set; }
    }
}

Add a new class, which inherits from the contract interface.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace SelfConsumingWcf
{
    [ServiceBehavior (InstanceContextMode = InstanceContextMode.Single)]
    class Learn : ILearn
    {
        private int sum = 0;

        public void Add (int incr)
        {
            try
            {
                sum += incr;
            }
            catch (Exception ex)
            {
                new FaultException (new ErrorInfo () { ErrorMessage = ex.Message });
            }
        }

        public int GetValue ()
        {
            return sum;
        }
    }
}

Implement the service OnStart and OnStop methods. After it, finish implementing the service.  Maybe seems the example is bit dummy, but its working. Of course you can implement other kind of logic, which will consume the self hosted service via the created ServiceFactory channel. I used similar manner to subscribe to an OPC Server to monitor the controlled items.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.ServiceModel;
using System.Text;
using System.Timers;

namespace SelfConsumingWcf
{
    public partial class Service1 : ServiceBase
    {
        public Service1 ()
        {
            InitializeComponent ();
        }

        private ILearn learnChannel;
        private ChannelFactory learnChFactory;

        private ServiceHost learnHost;
        private Timer timer;

        protected override void OnStart (string[] args)
        {
            if (learnHost != null)
                learnHost.Close ();

            learnHost = new ServiceHost (typeof (Learn));
            learnHost.Open ();
            learnChFactory = new ChannelFactory (
                learnHost.Description.Endpoints[0]);
            learnChannel = learnChFactory.CreateChannel ();

            timer = new Timer ();
            timer.Elapsed += timer_Elapsed;
            timer.Interval = 3000;
            timer.Start ();
        }

        private Random rnd = new Random ();

        void timer_Elapsed (object sender, ElapsedEventArgs e)
        {
            int direction = rnd.Next (0, 2);
            int num = rnd.Next (200);
            num = num * direction == 0 ? -1 : 1;
            learnChannel.Add (num);
        }

        protected override void OnStop ()
        {
            timer.Stop ();

            if (learnChFactory != null)
                learnChFactory.Close ();

            if (learnHost != null)
                learnHost.Close ();
        }
    }
}

Almost finally, need some configuration for the service. Well, that’s the part which can be a bit overwhelming. WCF configuration is a vast topic, and can be easily overlook something, or just a minor mistake, than the whole service will fail to work.

Add an Application configuration file and configure your service. You can do it manually or via Edit WCF configuration menu from Visual Studio, with right click on the app.config.

Configure the ABC:  Address, Binding, Contract

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="SelfConsumingWcf.Learn" behaviorConfiguration="LearnBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8000/SelfConsumingWcf/service"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="wsHttpBinding" contract="SelfConsumingWcf.ILearn"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="LearnBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

After finishing the code and configuration, you ready to go. Press F6 to build the project, than launch Visual Studio command promt or Command Promt with Administrative privileges. If you started VS command promt, than installutil is available for you, if you launched regular one, you need to go the corresponding Framework version folder, to install the service.
installutil –i [PathOfYourServiceExeFile]

Dependent from the install configurations you may ask the user name – password and maybe you need to start manually your service. If do, launch the services, to start the service. If everything is okay, you service will start, if not, you will receive a notification, you can check the details of the error in the Event Log, or the place where you store the error logs. If its work properly, you can check it in the browser.

Be a consumer.
Let the service running.  Launch WCF Test client or add a new project to the solution, reference the service, than test it.

Finally you can uninstall it, almost like as you installed:
installutil –u [PathOfYourServiceExeFile]