Using Castle Wcf Facility for Ridiculously Simple Services

The Castle Project has been releasing quality OSS components for many years. Most people are familiar with Castle Windsor and how easy it makes dependency management. I have been using the WCF Facility to make hosting and consuming WCF Services just as simple.

Let's start with a simple service definition, I have this code in a project named WCFDemo.Core.

using System.Runtime.Serialization;
using System.ServiceModel;

namespace WCFDemo.Core
{
    [ServiceContract]
    public interface IStringReverser
    {
        [OperationContract]
        ReverseResponse Reverse(ReverseRequest request);
    }

    [DataContract]
    public class ReverseRequest
    {
        [DataMember]
        public string Text { get; set; }
    }

    [DataContract]
    public class ReverseResponse
    {
        [DataMember]
        public string Text { get; set; }
    }
}

The implementation of the service is pretty straight forward.

using System.Linq;
using WCFDemo.Core;

namespace WCFDemo.Web.Services
{
    public class StringReverser : IStringReverser
    {
        public ReverseResponse Reverse(ReverseRequest request)
        {
            return new ReverseResponse
                {
                    Text = string.Join(string.Empty, request.Text.Reverse().ToArray())
                };
        }
    }
}

To host this service in a web application, you must create a web application project and reference Castle.Core, Castle.Windsor and Castle.Facilities.WcfIntegration. The first two are avaiable via NuGet the last you will have to get from the Castle Project CI Server.

Next, wire up Windsor in your Global.asax like this.

using Castle.Facilities.WcfIntegration;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using WCFDemo.Core;
using WCFDemo.Web.Services;

namespace WCFDemo.Web
{
    public class MvcApplication : System.Web.HttpApplication
    {
        public static WindsorContainer Container { get; set; }

        protected void Application_Start()
        {
           //...edited for clarity
            BuildContainer();
        }

        private void BuildContainer()
        {
            Container = new WindsorContainer();
            Container.Kernel.AddFacility<WcfFacility>();
            Container.Kernel.Register(Component.For<IStringReverser>()
                                               .ImplementedBy<StringReverser>()
                                               .Named("StringReverserService"));
        }
    }
}

Note that this example has been edited to only show the code needed to wire up Castle Windsor. Other MVC related code was removed for clarity.

The registration process is fairly simple. First create an instance of WindsorContainer, add the WcfFacility and finally register the service component. Notice that I have given the service a specific name "StringReverserService", this will be important in next step.

Next add a Wcf Service to the web application project. You can delete the code behind file and modifiy the .svc file like this.

<%@ ServiceHost 
    Factory="Castle.Facilities.WcfIntegration.DefaultServiceHostFactory, Castle.Facilities.WcfIntegration" 
    Service="StringReverserService" %>

Notice that the Service attribute matches the name given to the component registered in Castle Windsor. This name is used to resolve the type from the container. We can now browse the service.

Consuming the service is just as simple using the Wcf Facility. Here is an example of a simple Console application.

using System;
using System.ServiceModel;
using Castle.Facilities.WcfIntegration;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using WCFDemo.Core;

namespace WCFDemo.CLI
{
    class Program
    {
        static void Main(string[] args)
        {
            var container = GetContainer();
            var reverser = container.Resolve<IStringReverser>();

            while(true)
            {
                var input = Console.ReadLine();
                var output = reverser.Reverse(new ReverseRequest {Text = input});
                Console.WriteLine(output.Text);
            }
        }

        private static WindsorContainer GetContainer()
        {
            var container = new WindsorContainer();
            container.Kernel.AddFacility<WcfFacility>();
            container.Register(Component.For<IStringReverser>()
                                   .ActAs(new DefaultClientModel
                                       {
                                           Endpoint = WcfEndpoint.BoundTo(new BasicHttpBinding())
                                               .At("http://localhost:2484/StringReverser.svc")
                                       }));
            return container;
        }
    }
}

Here we register the IStringReverser component using the Wcf Facility api and start making calls on it. Cake!

You can find the full source code for this post up on GitHub right here. And here is a short video showing the service in action.

Follow me on Mastodon!