Search code examples
c#wcfproxywcf-proxy

How do I get WCF to generate a list of proxies?


How do I get WCF to generate a list or IEnumerable of proxies to the actual object? I'm doing this in a self-hosted application.

Here's what I have:

public interface IRemoteControlGroup {
     List<IRemoteControl> GetInstances();
}

public class RemoteControlGroupImpl : IRemoteControlGroup {
    public List<IRemoteControl> GetInstances()
    {
        System.Console.Error.WriteLine("Called GetInstances()");
        List<IRemoteControl> list = new List<IRemoteControl>();
        // implementation detail: get this list of IRemoteControl objects
        return list;
    }
}

public interface IRemoteControl {
     void Stop();
     void Start();
     void GetPID();
}

public class RemoteControlImpl : IRemoteControl {
     // actual implementation
}

I want WCF to:

  • Offer a service, RemoteControlGroupImpl, defined by the contract on IRemoteControlGroup.
  • Give me a List<IRemoteControl> when IRemoteControlGroup.GetInstances() is called (on the client), where elements of the list are proxies that implement IRemoteControl (by calling the host's actual IRemoteControl objects).

I don't want WCF to push actual RemoteControlImpl objects through the wire; I just want it to push proxies that implement IRemoteControl. RemoteControlImpl objects actually contain handles to the local system (Window handles, because our apps only expose a GUI interface), and therefore, are not serializable. The number of elements returned by GetInstance() can vary.

I found this article, which sounds like what I want. Kind of. But it doesn't tell me how to do this in code; just in the configuration. It also doesn't quite describe what I want. The entry point for the service delivers a proxy; but I want the entry point for my service to deliver a list of proxies.


Solution

  • As @John Saunders has pointed out you need to rethink your approach. I can think of a couple of general approaches that may be useful depending on what is driving your 'multiple' instances.

    1) If they are driven from outside the application (i.e. the list of available IRemoteControl targets does not change dynamically at run time), then you could expose the same contract via multiple endpoints. E.g. http://localhost/remotecontrol.svc/instance1, http://localhost/remotecontrol.svc/instance2, etc. The availability of the different endpoints can be publicised via your WSDL.

    2) If the multiple targets are dynamic then the simplest approach would be to redefine your contract:

    public interface IRemoteControlGroup {
         List<string> GetInstances();
         void Stop(string instanceId);
         void Start(string instanceId);
         void GetPID(string instanceId);
    }
    

    Internally your service would maintain a dictionary of available IRemoteControl objects, keyed by InstanceId and simply route the incoming operation to the target instance.