December 2005 - Posts

Andreas is blogging

Andreas is blogging! Stop by and drop him a welcome comment.

Andy and I have worked together for two different employers. He is a sharp guy with a passion for what he does, and I really look forward to reading his future posts. Hey, with a blog title like My Objective Opinion, you really can't go wrong. (I knew the world was in for trouble way back when I first saw that David West book on his desk)  :-)

message mapping, from service contract to component interface

The guys over at Thinktecture, namely Ingo and Ralf, have recently shared an interesting email discussion entitled "Interface design in distributed solutions". In the email thread, they discuss some of the similarities and differences between designing interfaces and contracts for services and components. In the end they develop a decision flowchart that can be used for rough generalizations on deciding which type of interface and contract designs to follow (component like patterns versus service like patterns). This is real interesting stuff and I enjoyed seeing the discussion develope the way it did. As Ralf states on his blog"because hearing contrasting thoughts next to each other sparks your own thoughts in a different way than reading a just an article explaining some subject"

Towards the end of the thread, they discuss the topic of mapping data between the service data contract and the component interface. Basically, what we are getting at here is message to domain modal mapping, or in a lot of cases message to object impedance.

Ralf and Ingo discuss 3 solutions for dealing with this, which correlate roughly to:

1) The service's data contract class implements component contract data interface

2) Use some sort of reflection based framework to perform the mapping (i.e. the service's contract class looks a lot like the component contract interface and so we let reflection handle the mapping)

3) Explicitly define the mapping

Seldom in the real world is the ratio of this mapping relationship forever 1/1. It may start out as 1. And if you are the same person, team, company building components on one side of a service, the service, and the components on the other side of the service, these "component interface to service contract" and "service contract to component interface" mapping ratios may be forced to 1. In which case it's very tempting to go down one of the two easier streets that are numbered choice 1 and 2. However, I generally look at these two options as falling into that camp of slippery slope stuff; similar to the messy ORM discussions that always rant back and forth in the object to relational mapping world.

I generally lean towards explicit mapping. Do it, get it over with and move on. I believe this is a similar mindset to what Udi is getting at when he says "In the end, the only real thing left is to map messages to service layer calls…" Additionally, after doing some good size mappings between service data contract and component interface myself, I can appreciate Buddhike's follow-up on desiring for this type of mapping to be a toolkit code generator thing; and, as long as that automation is "code generator" automation in an attempt to accomplish choice 3 then I'm good with that too. You can utilize reflection in tools to help generate this code at development time if you like; especially at the beginning of the process. But, I do think the explicit mapping is important (regardless if by hand or with code generator help) and I don't think the automation of the mapping is a runtime thing as I think is expressed in choice 2.

At some point in the lifetime relationship between the service and the component, stuff will need to happen. The component will need to change in ways that a service exposing it can't or shouldn't expose, or the service contract will need to change (extend). When this happens, there is impedance, and the ratio is no longer 1. Perhaps, the necessary extension of the service contract will require the creation of a separate component and thus one service data contract will now use data from two separate components. Perhaps, within the domain that the component belongs, one of the data members within it's contract interface will need to change dimension. Perhaps an integer needs to be a double (I know it sounds crazy, but we all know this stuff happens.) The explicit mapping gives you a point to do the necessary rounding and / or type coercions so the service data contract can remain consistent.

I do understand that Indigo uses an explicit "opt-in" model, and this is cool and has tremendous value and I'm really looking forward to it. However, despite this, I still think that any auto-generated (or attribute based serialization, etc) stuff from the service contract message into service contract class realm, still needs to be considered part of the "service domain" and not the domain in which component belongs. The service process may actually host and give life to some group of components, but this doesn't mean that the service domain encompasses the component domain; it uses the component domain and therefore should be linked to it in an adapter like way. This adapter process is the explicit mappings.

I also realize that in my example above where the service data contract is extended and requires the support of two components we could have the service data contract class implement two separate interfaces. Once again, I just think it is generally dangerous to skip the explicit mapping step from service domain to component domain; as tedious as it may be and as 1:1 trivial as it may seem early on. If time, or resource constraints do force you to skip the explicit mapping step, then keep it in mind down the road before deciding to bastardize the service or the component for the sole sake of the other.