将代码“挂钩”到WCF实例的正确方法?

时间:2010-03-10 11:18:35

标签: .net wcf

我启动并运行了WCF服务。我把它托管在一个win表单应用程序中,我想要有关于它的使用情况的各种统计数据在表单上实时显示。显然,我不希望WCF服务中的任何代码收集统计信息或处理任何GUI。

目前我正在努力在WCF服务中包含许多事件,这些事件允许表单添加侦听器以便它可以生成其统计信息。这是实现我的目标的正确方法还是有更多的WCF特定机制?

3 个答案:

答案 0 :(得分:1)

“标准”方法是使用性能计数器,但是如果您(曾/仅)想要向主机进程报告有点矫枉过正。

你可以使用事件+听众,对我来说似乎很好 或者使用简单的静态计数器和Interlocked.Increment(),这将是最快的方式。

答案 1 :(得分:1)

正如所建议的那样,静态计数器或事件和监听器在技术上可以做到这一点,但如果您的目标是更通用的解决方案,可以使用依赖注入(DI)来实现。

首先,您需要在WCF服务和托管应用程序之间共享Mediator。您可以从WCF服务向该Mediator写入消息,然后它可以将这些消息分发给主机中的相应处理程序。

您需要将Mediator注入您的WCF服务。您可以使用为服务合同分配自定义ServiceHost的自定义IInstanceProvider来执行此操作。在我的书第7章出来之前,我知道如何为WCF启用构造函数注入的最佳大纲是this blog post,如果你记住delegate is just an anonymous interface

有了这个,考虑将统计记录器实现为“真实”服务的Decorator,因为这样可以更好地分离关注点。像这样:

[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;
    }
}

在运行时,您可以将IMyService的“真实”实现与共享Mediator一起注入StatisticsDecorator。

如果您使用DI容器,您可能可以使用其拦截功能而不是手动滚动装饰器,但概念是相同的。

答案 2 :(得分:0)

WCF还提供开发自定义行为的功能,允许您检查和扩展服务方法调用的各个方面。例如,存在可定制的行为来检查方法参数,检查消息内容以及控制如何调用操作。 This MSDN杂志的文章很好地概述了自定义行为。

我不确定您的仪器需求是什么,因此我无法确定这是否适合您要做的事情。恕我直言,事件+听众也是一个可行的解决方案。也许甚至两者的某些组合可能是你最好的选择。