I've recently started using WCF and was surprised to find that the client class that is generated by Add Service Reference doesn't implement the interface of the ServiceContract
(let's call it IMyInterface
). Instead it implements System.ServiceModel.ClientBase<IAnotherInterface>, IAnotherInterface
where IAnInterface
is an interface that is like my ServiceContract interface but not actually the same one. I see that some of the types are different, e.g. it has arrays instead of Lists.
This is a bit annoying for me as sometimes I want to make remote calls to a web service and sometimes want to use a local object, so I want them to implement the same interface. Currently I'm wrapping the ClientBase
object in another one so it does implement the same interface, and in that just passing all calls through to the ClientBase
object. Is this the recommended approach or is there an easier way?
I see I can change the types of the collection parameters from array to List or whatever on Configure Service Reference, but doubt that'll solve the basic typing issue.
The default behavior for WCF is exactly what you're seeing: the service and the client are totally independent of one another - after all with the idea of being interoperable, you cannot rely on the client being .NET, too - it could be Ruby, Python - you name it.
Therefore, when a client proxy gets created, the only thing that the client and the service share is the format of the messages on the wire, and in the case of SOAP the WSDL description of the service. The client-side proxy gets recreated based on this metadata, with the goal of providing the same methods to call, and the same data structures to use for serializing messages to the service.
If you can control both ends of the communication and both are .NET, then you can skip one of those steps by putting your service and data contracts into a separate class library, and sharing that assembly (and thus those exact interfaces and classes) between the service and the client.
When your client project references that shared assembly, and now goes to add a service reference and you leave the default options in place in the dialog, then the behavior is to re-use any existing classes and interfaces from referenced assemblies when possible. So in this case, if you add the service reference, the generator for the client-side proxy finds those classes that perfectly match your service description, and just uses those instead of generating a separate, independent set of classes and interfaces.