Thursday, March 10, 2011

Hosting WCF in a Managed Environment

Prerequisite: Basic Knowledge about WCF.

There are various options available to host a WCF service like
1)      Managed Environment (.NET Window Service or a Console Application)
2)      IIS
3)      WAS etc.
 This blog is a quick start tutorial to develop and host a WCF service on a managed environment. It does not brief about the WCF architecture or its advantages. I am sharing my attempt to create and host a WCF service in a managed environment with very minimal configuration and code.  
Following are the basic entities required to create the WCF Service,
1)      Interface definition with Service attributes and Operation contracts.
2)      Class that implements the interface
3)      Server application (a console application in this example) to register and host the service

Interface Definition:
                Create a Project WCFServiceLibrary as a plain C# console application. WCF service interface should be decorated with ServiceContract attribute to mark this as the service that is exposed. Individual methods should be decorated with OperationContract to mark them as the end points available in the service. Copy and Paste this code into IMyFirstWCFService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace WCFServiceLibrary
{
    [ServiceContract]
    interface IMyFirstWCFService
    {
        [OperationContract]
        string GetData(int i);
    }
}

Interface Implementation:
                This is the simple class that implements the interface. This class will be exposed as the Service by the ServiceHost object. Copy and Paste this code into MyFirstWCFService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WCFServiceLibrary
{
    public class MyFirstWCFService : IMyFirstWCFService
    {
        public string GetData(int i)
        {
            return "You have entered : " + i.ToString();
        }
    }
}

Service:
                Once the interface and the implementation classes are ready, we need a background service to register and host the WCF Service. Copy and Paste the following code to HostingService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace WCFServiceLibrary
{
    public class HostingService
    {
        public static void Main()
        {
            using (ServiceHost sh = new ServiceHost(typeof(MyFirstWCFService), new Uri("http://localhost:8080/Service")))
            {
                ServiceMetadataBehavior sm = new ServiceMetadataBehavior();
                sm.HttpGetEnabled = true;
                sm.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
                sh.Description.Behaviors.Add(sm);
                sh.AddServiceEndpoint(typeof(IMyFirstWCFService), new BasicHttpBinding(), "MyFirstWCFService");
                sh.Open();
                Console.ReadLine();
                sh.Close();
            }
        }
    }
}

Now run the project and alas you have hosted a WCF service in just few minutes. The code in the HostingService is self explanatory. All that is required is to create a ServiceHost with the Interface and BaseURI. Create metadabehaviour and add endpoints to the ServiceHost. Now to test if the service has been hosted correctly, open a browser and type the URL http://localhost:8080/Service. You should see a screen shot similar to the one below


Alternately you can use an app.config to define the baseURI, MetadataBehaviour, Binding and Endpoint information. Copy and Paste the following code to HostingService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace WCFServiceLibrary
{
    public class HostingService
    {
        public static void Main()
        {
            using (ServiceHost sh = new ServiceHost(typeof(MyFirstWCFService)))
            {
                sh.Open();
                Console.ReadLine();
                sh.Close();
            }
        }
    }
}

Copy and paste the following code to App.Config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="WCFServiceLibrary.MyFirstWCFService" behaviorConfiguration="WCFServiceLibrary.MyFirstWCFServiceBehaviour">
        <host>
          <baseAddresses>
            <add baseAddress = "http://localhost:8080/Service" />
          </baseAddresses>
        </host>
        <endpoint address="MyFirstWebService" binding="wsHttpBinding" contract="WCFServiceLibrary.IMyFirstWCFService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WCFServiceLibrary.MyFirstWCFServiceBehaviour">
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

That’s all is required. Test the service in the similar way to make sure it’s hosted correctly. Now you have to just provide the wsdl URL http://localhost:8080/Service?wsdl) to the client to consume the services that you have just exposed.

Note: Remember that the console application should be alive and running for you Clients to consume it. Alternatively, you can use the same code to host it in a Windows Service with a little tweak to have them running as service at the background.