Search code examples
.netwcfwcf-bindingnettcpbinding

Dynamically set endpoint address in wcf client (with net tcp binding)


So I'm not overly familiar with WCF and all the stuff I've googled hasn't helped me with how to achieve what I need. Sorry if this is a dumb question :)

Basically there is a server app with services exposed with WCF (net tcp binding). I've written a new console app and I need to call the service. So I can achieve this by adding a dll for the proxy project we have and by adding a bunch of config files (such as WCFClientBindings, WCFClientEndPoints). If I use a defined end point then I can call code like this:

using (var partyProxy = new PartyControllerProxy())
            {
                // execute server method 
                partyProfile = partyProxy.GetLatestPartyProfile(context, parsedParameters.PartyId);
            }

However the app is supposed to be able to call the hostname that is passed in as a command line argument.

So whilst my app works with a defined endpoint:

<client>
  <endpoint
  name="IPartyControllerEndpoint"
  address="net.tcp://localhost:46000/ServiceInterface/PartyController.svc"
  binding="customBinding" bindingConfiguration="DefaultNetTcpBindingConfiguration"
  contract="CompanyA.Service.Product.Core.Contracts.IPartyController"
  behaviorConfiguration="DefaultEndpointBehavior">
  </endpoint>
</client>

I need to be able to update the localhost hostname to be potentially something else. Am hoping that security doesn't trip me up :)

The examples I've seen seem to instantiate the client/proxy by passing in the "dynamic" binding and address, but our proxy class doesn't accept those. Isn't there a way to update the address of the endpoint (at runtime) before calling the "proxy" class ? The only other examples I've seen have involved instantiating a new ServiceHost - but that doesn't sound very appropriate for the client :)

Thanks!

Edit - OK here's the syntax that seems to work nicely. It's a little different to the answer I accepted, but that approach was the way to go :)

using (ChannelFactory<IPartyController> factory = new ChannelFactory<IPartyController>("IPartyControllerEndpoint"))
        {
            EndpointAddress address = new EndpointAddress(String.Format("net.tcp://{0}/ServiceInterface/PartyController.svc", parsedParameters.HostName));
            IPartyController channel = factory.CreateChannel(address);

            partyProfile = channel.GetLatestPartyProfile(context, parsedParameters.PartyId);
            ((IClientChannel)channel).Close();
        }

Solution

  • You could create a ChannelFactory.

    Along with your standard client, WCF WSDLs will also provide an interface class for the client.

    EndpointAddress address = new EndpointAddress("http://dynamic.address.here");
            using (ChannelFactory<IPartyControllerChannel> factory = new ChannelFactory<IPartyControllerChannel>("IPartyControllerEndpoint", address))
            {
    
                using (IPartyControllerChannel channel = factory.CreateChannel())
                {
                    channel.GetLatestPartyProfile(context, parsedParameters.PartyId);
                }
            }