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.