Search code examples
wcfwcf-client

How do I pass a service to another plugin?


I have a plugin that I will instantiate at runtime and I want to pass it a WCF service from the application host. The application host is responsible for creating the connection to the service. The reason for this is that a single service can be used by multiple plugins, but the plugins should only know about its interface since there may be several implementation of IMyPluginServices. For instance, the Run method of the plugin instance would be:

    public void Run(IMyPluginServices services)
    {
        services.DoSomething();
    }

The problem I am running into is that I don't know how to create a service of type IMyPluginServices and pass it to the Run function. The service reference generated by VS 2010 doesn't seem to create an object of type IMyPluginServices that I can pass to it. Any help would be greatly appreciated. Thanks.


Solution

  • When you add a service reference in VS 2010 for a service it generates an interface named IMyService which contains methods for each OperationContract in your service. It also generates a concrete class named MyServiceClient, which can be constructed and then used to invoke your service.

    Now, the problem that you're running into, I believe, is that MyServiceClient is a subclass of ClientBase<IMyService>, and does not implement the generated IMyService interface (which is a real pain).

    To get around this problem I ended up making a new interface:

    public interface IMyServiceClient : IMyService, IDisposable, ICommunicationObject
    {
    }
    

    (Note: IDisposable and ICommunicationObject are only required if you want your module to be able to detect/react to faulted channels and other such things).

    I then extend MyServiceClient with a partial class (in the assembly that contains my WCF Service reference):

    public partial class MyServiceClient : IMyServiceClient
    {
    }
    

    Now in my modules I can accept an IMyServiceClient instead of an IMyService, and still execute all of the methods that I need to. The application in control of the modules can still create instances of MyServiceClient as it always did.

    The beauty of this is that your new interface and partial class don't need any actual code - the definitions suffice to get the job done.