简体   繁体   中英

WCF Proxy Behaviors and Params

Using an IExtension, I've made a client-side behavior that takes a parameter from whatever client is using the proxy. And while my approach works, I want a better way.

Now I'll share details of my current working approach, to clarify what I'm trying to do.

The client using the proxy supplies the parameter like this:

var client = new ServiceAlphaClient();

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

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

client.Close();

The IExtension ParameterHolder looks like this:

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
}

The client-side behavior-extension which uses the parameter looks like this:

    #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

What I don't like about all the above:

  1. The ClientMessageInspector extension is repeatedly calling Extensions.Find for every outgoing request. That is both needless and inefficient.
  2. The client using my proxy must supply the parameter for each new proxy created.

Regarding the first problem, in the inspector extension I could store and test for the value for better efficiency, but I'd rather be able to fetch this parameter just once at an earlier stage. Specifically, I'd like the IContractBehavior itself to be able to fetch the parameter either in AddBindingParameters(...) or ApplyClientBehavior(...). But I don't know how to reach the client channel from there.

Regarding the second problem, I'd prefer not to set the parameter on each proxy instance with Extensions.Add(). I wish I could set the parameter statically on the client, and somehow still have the behavior extension reach-back and fetch it. I can't quite figure how to leverage a partial class to help.

Anyway to solve these problems? Have an overall better approach for passing "meta-parameters" to a WCF proxy?

Forgive me if I wrongly interpreted your problem. But the solution that can solve both your problems is to put a public static member (property or field) in your inspector class. So the client just need to the set the parameter once, and your inspector method can access them too.

So your inspector class should be look like this:

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

} 

and you client, just need to assign MyproxyInspector.MyParam once somewhere convenient in your client code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM