R – wcf exposing generics

genericswcfwcf-binding

I have an application where client and server share types, and interoperability is not one of our concerns. I am planning to have a single repository for all web enabled objects, and i was thinking of a generic interface for my exposed service.

something like T GetObject(int id)

but wcf doesnt like it since its trying to expose its schema (which i dont really care about)

is it possible to do such a thing with WCF ?, i can use any type of binding doesnt have to be httpbinding or wsbinding…

Best Answer

I suppose this is possible, though I'm not sure you'd want this. I'd take the following approach (untested, not sure if it works). First create the following project structure in your solution:

  • ServiceInterfaces
  • ServiceImplementations (references ServiceInterfaces and ModelClasses)
  • ModelClasses
  • Host (references ServiceInterfaces and ServiceImplementations)
  • Client (references ServiceInterfaces and ModelClasses)

In ServiceInterfaces you have an interface like this (I skipped the namespaces, etc to make the example shorter):

[ServiceContract]
public interface IMyService<T>
{
    T GetObject(int id);
}

In ServiceImplementations you have a class that implements IMyService<T>:

public class MyService<T> : IMyService<T>
{
    T GetObject(int id)
    {
        // Create something of type T and return it. Rather difficult
        // since you only know the type at runtime.
    }
}

In Host you have the correct configuration for your service in an App.config (or Web.config) file and the following code to host your service (given that it is a stand-alone app):

ServiceHost host = new ServiceHost(typeof(MessageManager.MessageManagerService))
host.Open();

And finally in Client you use a ChannelFactory<TChannel> class to define a proxy:

Binding binding = new BasicHttpBinding(); // For the example, could be another binding.
EndpointAddress address = new EndpointAddress("http://localhost:8000/......");
IMyService<string> myService =
    ChannelFactory<IMyService<string>>.CreateChannel(binding, address);
string myObject = myService.GetObject(42);

Again, I'm not sure if this works. The trick is to share your service interfaces (in ServiceInterfaces) and domain model objects (in ModelClasses) between the host and the client. In my example I use a string to return from the service method but it could be any data contract type from the ModelClasses project.

Related Topic