views:

33

answers:

1

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.

+1  A: 

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.

Andrew Anderson
Wow! Thanks. You're solution works like a charm. I wonder why MS didn't think of this particular scenario since it is common to share a connection between objects.
Joel Rodgers
One more thing. This particular solution requires that all of the plugins and the host reference the service contract. This introduces coupling. I wonder what problems, if any, can happen if the contract changes. I don't really see much of an issue.
Joel Rodgers
Glad it worked for you. I ended up scratching my head for a day trying to solve exactly the same issue earlier this month, so am happy to share.I do agree that the tight binding to the service project is a bit of a pain, however I don't see any way around it given that you want to call methods from that service.
Andrew Anderson
Oh wait - Saturday afternoon talking. You can get around the coupling if you use injection, and have the modules stand up their own instances of the service. My full solution actually does that.More on Monday, if I think of it.
Andrew Anderson