Thursday, 19 June 2008

wcf primer 8 - location agnostic programming is here!

Please find the landing page here.

In the previous post in this series, I talked about the fact that I think that not sharing the interface definition when possible (ie when you have an  assembly/project reference to the dll containing the interface) is a huge mistake. So, this is the promised elaboration on that post.

When dinosaurs roamed this planet

If you remember the pre-WCF days we had a number of transport stacks, each with their own needs:

  • remoting
    Inherit from MarshallByRef, objects that are being sent need to be Serializable (Binary, Xml)...
    To build a client, you need to have a common set of dlls (object and contract)
  • web services
    Methods needs to have the [WebMethod] attribute, objects that are being sent are serialized via the XmlSerializer
    To build a web servcie client, you create a proxy to a web service (wsdl), which generates client code.
    There is a way to share the objects sent on both client and server, but that one is frowned upon by SOA purists.
  • ..

 

location agnostic programming

LAP stands for one way of programming, regardless of transport/layers and so on.
As a prerequisite for understanding the next step you might want to read a case for dependency injection
The essence of that post i can repeat here

ISomething something = Container.Resolve<ISomething>();

LAP is typically something that you can do by combining a creational pattern and interface based programming,
as it always you to get back an object that implements the required interface.

pre WCF LAP

So why does LAP become feasable with the arrival of WCF? 
Consider the following scenario:

You are building a client to a 'service' which can be exposed via either remoting or web services.
The choice of transport stack shouldn't have any consequences for the rest of the client code.

Business logic:

ISomething myService = SomeFactory.Create();
myService.Foo();

Remoting implementation (it's been a while)

public class RemotingProxy : ISomething{
private ISometing _remote;
public RemotingProxy(){
TcpClientChannel channel = new TcpClientChannel();
ChannelServices.RegisterChannel(channel);
_remote = (ISomething) Activator.GetObject(typeof(ISomething),"tcp://something", ISomething);
}
public void Foo(){
  _remote.Foo();
}
}

Web service implementation (note here that you're just 'applying' an interface over the web service proxy, something you can also do via partial classes from .net 2.0 onward.

public class WSProxy : ISomething{
private Webservice.proxy _proxy = new Webservice.Proxy();
public void Foo(){
_proxy.Foo();
}
}

in process implementation (the real business logic)
public class BusinessLogic : ISomething{
void Foo(){
// your logic here
}
}

So in the end, what does this give you?
One implementation per transport protocol + 1 for business logic

WCF LAP

So why is WCF better than sliced bread?  Basically because it takes away the 'one implementation per transport protocol' annoyance.  Or beter said, it should take it away...

As said before, when creating a new service client using vs2008 the implemented interfaces is renamed to the client's namespace, breaking the desired IOC/DI capabilities.  So, we still roll our own service client's but at least you're only doing it once :)

0 comments: