Wednesday, February 5, 2014

Quick and easy self-hosted WCF services

I realized that I am not writing blogs for a long time. I feel bad about that, this post is an attempt to get out of the laziness.


I often find myself writing console applications that have a simple WCF service and a client that invokes that to check different stuffs. Most of the time, I want to have a quick service that is hosted using either NetTcpBinding or WsHttpBinding with very basic configurations. Which triggers the urge writing a bootstrap mechanism to easily write and host WCF services and consume them at ease. I am planning to extend the implementation into a more richer one gradually, but I have something already to do a decent kick off. Here's how it works.


Step 1 : Creating the contract


You need to create a class library where you can have your contract interfaces for the service you are planning to write. Something like following

    [ServiceContract(Namespace = "http://abc.com/enterpriseservices")]
    public interface IWcf
    {
        [OperationContract]
        string Greet(string name);
    }

Now you need to copy the WcfService.cs file into the same project. This file contain one big class named WcfService. That has the public methods to host services and also creating client proxies to invoke them. The class can be downloaded from this Git (https://github.com/MoimHossain/WcfServer) repository. Once you have it added into your project, go to step 2.


Step 2 : Creating Console Server project.


Create a console application that will host the service. Add a reference to the project created in step 1. Define your service implementation class as follows


    // Sample service
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class MyService : IWcf
    {
        public string Greet(string name)
        {
            return DateTime.Now.ToString() + name;
        }
    }

Finally modify the program.cs to have something like following

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // use WcfService.Tcp for NetTcp binding or WcfService.Http for WSHttpBinding

                var hosts = WcfService.DefaultFactory.CreateServers(
                    new List { typeof(MyService) },
                    (t) => { return t.Name; },
                    (t) => { return typeof(IWcf); },
                    "WcfServices",
                    8789,
                    (sender, exception) => { Trace.Write(exception); },
                    (msg) => { Trace.Write(msg); },
                    (msg) => { Trace.Write(msg); },
                    (msg) => { Trace.Write(msg); });

                Console.WriteLine("Server started....");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            Console.ReadKey();
        }
    }


At this point you should be able to hit F5 and run the server console program.


Step 3 : Creating Console client project


Create another console application and modify the program.cs to something like following


    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // use WcfService.Tcp for NetTcp binding or WcfService.Http for WSHttpBinding

                using (var wcf = 
                    WcfService.DefaultFactory.CreateChannel(Environment.MachineName, 8789, (t) => { return "MyService"; }, "WcfServices"))
                {
                    var result = wcf.Client.Greet("Moim");

                    Console.WriteLine(result);
                }
            }            
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }

You are good to go! Hope this helps somebody (at least myself).

No comments:

Post a Comment