WcfLib - WCF services, clients, and routers

Reading time ~3 minutes

Describes the WcfLib component, for easily creating Wcf services, clients, and routers. These are useful for creating and communicating with WCF services, particularly in Azure environments which require WCF routing capabilities. Available as a (WcfLib NuGet Library)

Background

I’ve been working with a customer who was looking to re-host one of their existing applications in the Microsoft Azure Service Fabric environment.

This particular application uses Windows Communication Foundation (WCF) framework for communication between clients and services. However when hosting applications in Azure Service Fabric, clients typically do not directly connect to services, but utilize a router or gateway to talk to the services (see next article on a Fabric router).

This component allows one to easily create WCF routers, and then further, allows extension points to enhance theat routing with additional information (such as that needed in a Service Fabric environment). Additionally, by being able to build routers that can run locally during development, you can isolate application communication issues from issues of the service hosting environment. When working in Azure this is particularly helpful.

Windows Communication Foundation (WCF)

The basics of WCF are creating a service contract interface, implementing that interface in a service, and referencing that interface in a client. Here is a useful glossary of common terms.

The service contract

Here’s an example of a service contract interface:

using Wcf = System.ServiceModel;
namespace WcfLibTests
{
    [Wcf.ServiceContract]
    public interface IFoo
    {
        [Wcf.OperationContract]
        string GetName();

        [Wcf.OperationContract]
        void SetName(string name);

        [Wcf.OperationContract]
        int GetValue();

        [Wcf.OperationContract]
        void SetValue(int value);
    }
}

and here’s an example of the implementation:

using Wcf = System.ServiceModel;
namespace WcfLibTests
{
    public class Foo : IFoo
    {
        public string Name { get; set; }
        public int Value { get; set; }

        public string GetName()
        {
            return this.Name;
        }

        public int GetValue()
        {
            return this.Value;
        }

        public void SetName(string name)
        {
            this.Name = name;
        }

        public void SetValue(int value)
        {
            this.Value = value;
        }
    }
}

both of the above definitions are used in the unit tests provided in the WcfLib GitHub Repo.

Most of the online documentation and samples use xml configuration for declaring the service and client details. This component does all declaration programmatically, with no additional xml configuration required.

Creating a service

To create a basic TCP WCF service, once you have included the WcfLib NuGet Library you can create the service host:

var service = new TcpService();

And initialize it with the Uri it will listen on, and an instance of your contract implementation:

var path = new Uri("Tcp://localhost:8088/");
var foo = new Foo();
service.Initialize(path, foo);

Creating a custom WCF router

To create a router, you will need to define a Filter and Resolver.

Filter

The Filter base class, provides a default implementation of a WCF MessageFilter, that implements endpoint Uri matching.

These methods can be overridden to provide more fine-grained matching behavior: - Initialize - Equals - Match

The basic TestFilter uses the default matching behavior:

public class TestFilter : Filter
{
}

Resolver

The Resolver base class encapsulates the implementation of an IDispatchMessageInspector and IEndpointBehavior.

It requires the override of 2 abstract methods: - CreateFilter - UpdateFilter

For our TestResolver unit test, we implemented these methods as:

public override Task<Filter> CreateFilter(Message request)
{
    TestFilter filter = null;
    // resolve the "To" address as the matching entry
    foreach (var f in services)
    {
        if (f.Service.Uri.AbsolutePath == request.Headers.To.AbsolutePath)
        {
            filter = new TestFilter();
            filter.Initialize(request.Headers.To, new Uri[] { f.Uri });
            break;
        }
    }
    return Task.FromResult<Filter>(filter);
}

public override Task<Filter> UpdateFilter(Message request, Filter oldfilter)
{
    var filter = new TestFilter();
    filter.Initialize(request.Headers.To, new Uri[] { oldfilter.Endpoints[0].Address.Uri });
    return Task.FromResult<Filter>(filter);
}

Ideas for improvements

In creating the unit tests, I noticed a common pattern for creating a service with a particular transport, so it might be possible to use generics to further generalize the service pattern usage.

References

This is a collection of links to articles and references that I used during this development:

Using your WebSocket in JavaScript

Extends the previous WebSocket sample by providing a generic JavaScriptpage that exercises a WebSocket endpoint. [Example code is on Git...… Continue reading

Websockets in Asp.Net Core

Published on July 28, 2016

A new NLogEtw component

Published on October 19, 2015