tags:

views:

38

answers:

2

I have a WCF service up and running. I have it hosted in a win forms app and I want to have various statistics about it's usage being displayed in real time on the form. Obviously I don't want any code in the WCF service to collect the statistics or handle any GUI.

Currently I am working towards having a number of events inside the WCF service which would allow the form to add listeners to so that it can produce its statistics. Is this the correct way to achieve my goal or is there a more WCF specific mechanism for it?

+1  A: 

As has been suggested, static counters or events and listeners may technically do the trick, but if you aim for a more general-purpose solutions, it can be implemented with Dependency Injection (DI).

First of all, you need an Mediator that is shared between the WCF service and the hosting application. You can write messages to that Mediator from the WCF service and it can then distribute those messages to the appropriate handlers in the host.

You need to inject the Mediator into your WCF service. You can do that by using a custom ServiceHost that assigns a custom IInstanceProvider to the service contract. Until chapter 7 of my book is out, the best outline I know of how to enable Constructor Injection for WCF is this blog post if you keep in mind that a delegate is just an anonymous interface.

With that in place, consider implementing the statistics logger as a Decorator to the 'real' service, as this will give you better separation of concerns. Something like this:

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    Foo DoStuff(Bar bar);
}

public class StatisticsDecorator : IMyService
{
    private readonly IMyService service;
    private readonly IMediator mediator;

    public StatisticsDecorator(IMyService service, IMediator mediator)
    {
        if(service == null)
        {
            throw new ArgumentNullException("service");
        }
        if(mediator == null)
        {
            throw new ArgumentNullException("mediator");
        }

        this.service = service;
        this.mediator = mediator;
    }

    public Foo DoStuff(Bar bar)
    {
        this.mediator.SignalBeforeDoStuff();
        var result = this.service.DoStuff(bar);
        this.mediator.SignalAferDoStuff();
        return result;
    }
}

At run-time, you would then inject the 'real' implementation of IMyService into StatisticsDecorator together with the shared Mediator.

If you use a DI Container, you might be able to use its interception capabilities instead of hand-rolling a Decorator, but the concept is the same.

Mark Seemann
A: 

WCF also provides the ability to develop custom behaviors, allowing you to inspect and extend aspects of the service method invocation. For example, customizable behaviors exist to inspect the method parameters, to inspect the message contents, and to control how an operation is invoked. This MSDN magazine article is a good overview of custom behaviors.

I'm not sure of what your instrumentation needs are, so I can't really say whether or not this is appropriate to what you're looking to do. IMHO, the events+listeners are also a viable solution. Perhaps even some combination of the two may be your best bet.

Jesse Squire