Wednesday, March 18, 2009

Generics with WCF

Like many others, I really miss generics in web services (SOAP). As a part of my work, I write and see other people writing many a web-services and I get really upset with the amount of duplicate code it has.

Polymorphism helps, an operation contract like


[OperationContract]
IEntity Find(IEntity entity);


is valid and works of all classes derived from IEntity. But in general, I missed power of generics.

I figured out a simple way (with WCF) to salvage some pride. I figured out that a service implementation could derive from a generic service contract (and generic implementation class). Have a look.

I have a generic service contract


[ServiceContract]
public interface IService<T> where T : IEntity
{

[OperationContract]
void Create(T entity);

[OperationContract]
void Update(T entity);

[OperationContract]
void Delete(string id);

[OperationContract]
T Find(T entity);

}


and a generic implementation


public abstract class ServiceBase<T> : IService<T> where T : IEntity
{

#region IService<T> Members

public virtual void Create(T entity)
{
}

public virtual void Update(T entity)
{
}

public virtual void Delete(string id)
{
}

public virtual T Find(T entity)
{
  return entity;
}

#endregion

}

I can now add a service that would inherit implementations of ServiceBase<T>. I just need a small workaround.

I first create a dummy service contract


[ServiceContract]
public interface IService :IService<Entity>
{
}

and then implement my service from this contract as


public class Service : ServiceBase<Entity>, IService
{

//all implementations of service base (for Entity) are inherited.
//you may override the way you wish :)

}

that's it.

Although I need to add one endpoint (different services would do) for each instance (each subclass of IEntity you want to expose) of this implementation (the sad part but I think limited by SOAP itself), this is still powerful in order to avoid code duplication and maintain strong typing (to some extent).