2

使用 IExtension,我创建了一个客户端行为,该行为从使用代理的任何客户端获取参数。虽然我的方法有效,但我想要更好的方法。

现在我将分享我当前工作方法的详细信息,以澄清我正在尝试做的事情。

使用代理的客户端提供如下参数:

var client = new ServiceAlphaClient();

client.InnerChannel.Extensions.Add(new ParameterHolder("hello"));

client.DoSomething("some interesting service invocation");

client.Close();

IExtensionParameterHolder如下所示:

public class ParameterHolder: IExtension<IContextChannel>
{

    public string someParam;

    public ParameterHolder(string someParam)
    {
        this.someParam = someParam;
    }

    #region IExtension required-but-useless stuff
    public void Attach(IContextChannel owner)
    {
    }

    public void Detach(IContextChannel owner)
    {
    }
    #endregion
}

使用该参数的客户端行为扩展如下所示:

    #region IClientMessageInspector
    public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
    {
        //throw new NotImplementedException();
    }

    public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
    {
        ParameterHolder holder = channel.Extensions.Find<ParameterHolder>();

        string param = holder.someParam;

        request.Headers.Add(MessageHeader.CreateHeader(headerName, headerNamespace, someParam));
        return null;
    }
    #endregion

我不喜欢以上所有内容:

  1. ClientMessageInspector 扩展为每个传出请求重复调用 Extensions.Find。这是不必要的,也是低效的。
  2. 使用我的代理的客户端必须为创建的每个新代理提供参数。

关于第一个问题,在检查器扩展中,我可以存储并测试该值以获得更高的效率,但我宁愿能够在较早阶段仅获取此参数一次。具体来说,我希望 IContractBehavior 本身能够在 AddBindingParameters(...) 或 ApplyClientBehavior(...) 中获取参数。但我不知道如何从那里到达客户渠道。

关于第二个问题,我不希望使用 Extensions.Add() 在每个代理实例上设置参数。我希望我可以在客户端上静态设置参数,并且以某种方式仍然可以让行为扩展返回并获取它。我不太清楚如何利用部分类来提供帮助。

无论如何要解决这些问题?将“元参数”传递给 WCF 代理有更好的整体方法吗?

4

1 回答 1

0

如果我错误地解释了您的问题,请原谅我。但是可以解决这两个问题的解决方案是在检查器类中放置一个公共静态成员(属性或字段)。所以客户端只需要设置一次参数,你的inspector方法也可以访问它们。

所以你的检查员类应该是这样的:

Class MyProxyInspector:IClientMessageInspector
{
    public static string MyParam;

    ...

    public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
    {
        request.Headers.Add(MessageHeader.CreateHeader(headerName, headerNamespace, MyParam));
        return null;
    }

} 

而您的客户,只需在您的客户代码中方便的地方分配一次 MyproxyInspector.MyParam 。

于 2013-03-22T10:00:34.113 回答