Building the often needed anti-corruption layer

The fear of the LORD is the beginning of knowledge, But fools despise wisdom and instruction.  — Proverbs 1:7

Agile Joe” and I were chatting about the challenges of building on top of existing application platforms, specifically ones like Microsoft CRM (which Ayende is painfully dealing with) and Commerce Server 2007, which is what I’m dealing with on my current project.  Joe pointed out the importance of building an anti-corrruption layer.  And I couldn’t agree more.  In fact, since I’m using DDD as much as I can on this project, we’ve been able to deliver early customer demos showing working features, end to end, using stubbed repositories. 

To get a better picture, this is basically how the design of the system is shaping up so far:

MVC Web UI MonoRail of course.  :)
DTOs (Screen-specific) 2 way databound using MonoRail’s most excellent DataBinder
Thin Service Layer To simply act as a facade to expose business operations and to handle the DTO => Domain Object mappings
Domain Model With all the entities, value objects, factories, specifications, etc. that you would expect.  I also keep the public interfaces to my Repositories in my domain model, but the specific implementations of them in a Persistence layer.
Persistence Layer – Stubbed These are just some in-memory repository implementations which have allowed us to demonstrate working features to the customer very early in the project.
Persistence Layer – CS 2007? This one is yet to be, but is what I have in mind when we start integrating with CS 2007 soon.  This would basically act as our “anti-corruption layer” between CS 2007 and our domain model.

 

It seems the recommended approach for implementing an anti-corruption layer is to treat is as another Service Layer.  From our perspective, I don’t see much of a difference in using Repository implementations in the same way.  Especially since in our case, most of our integration with Commerce Server will be dealing with persisting/retrieving data.  On a related note, I’m starting to realize that MS application platforms like Commerce Server are nothing more than a pre-built legacy database for your application.  Hence the need to localize the nastiness involved with extending and integrating with it, in an anti-corruption layer.

The one advantage I do see by treating this integration layer as another Service Layer, is in the fact that in reality there will be a lot more going on behind the scenes besides just a bunch of persistence method calls.  Since Commerce Server has its own wannabe entities in the form of weakly-typed datasets (yes! you heard that right) and untestable classes, we’re going to have to build another set of mappers that can translate between our domain model and our extended CS 2007 “entities”.  Along with things dealing with the CS 2007 context, etc. 

We’ve already identified the need to have an extensive set of automated integration tests to drive out this anti-corruption layer.  So I’m sure I’ll have a lot more to say on that as we progress.  Unfortunately it looks like it’s going to require some fairly complex test set up logic to get a test instance of CS 2007 configured in an automated fashion.

Like most instances where you have to extend and integrate with an existing platform such as Commerce Server, I keep wondering if all this time we’re having to spend will be worth it vs. “rolling our own” as they say.  Guess we’ll see.

Any thoughts on this approach?  Am I just completely mad?  :)

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

This entry was posted in commerce server, domain-driven design, monorail, patterns. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

4 Responses to Building the often needed anti-corruption layer

  1. Jimmy Bogard says:

    Just a word of warning, I know some people that were trying to do the exact same thing with an older version of Commerce Server. By the time they had finished, it was time to upgrade to the new version, at which time they had to start completely over.

    It can be easy to put some anti-corruption layer around a foreign context, model, or service. Building an anti-corruption layer around the platform you’re building upon is far more daunting.

    A different option is to use bounded contexts. Your anti-corruption layer isn’t a logical layer that you mentioned above, but a set of messaging services designed to keep the two contexts synchronized. You keep a separate domain model AND data model, and use a set of integration pieces to tie them together as needed.

  2. joeyDotNet says:

    “By the time they had finished, it was time to upgrade to the new version, at which time they had to start completely over.”

    That’s actually another good point as why building on top of a platform like that can be challenging. But hopefully, by keeping things loosely coupled, the impact of such an upgrade (IF it ever happens) won’t force us to “start over”. So far, we’ve managed to keep things isolated pretty well. Hopefully we’ll be able to continue in that as we integrate with CS 2007.

    “Your anti-corruption layer isn’t a logical layer that you mentioned above, but a set of messaging services designed to keep the two contexts synchronized. You keep a separate domain model AND data model, and use a set of integration pieces to tie them together as needed.”

    Thanks, it’s actually great to hear of a different approach. Bounded contexts is one of the areas of DDD that I haven’t learned nearly enough about. So I guess now I really need to. We do absolutely understand that we’re going to have a whole different set of “entities” (extended from CS 2007′s) and data model to manage.

  3. Can you elaborate on how you manage your “per-screen” dto’s?

    I have dto’s for my entities, but they are really just dumb row-containers that don’t contain any other references or data types, just flat values. My problem with using these for my UI is that I lose most of the functionality that I was gaining by having entities.

    If my presenter talks only to services (that are probably inProc, but they might be remote) then messages have to be purely DTO (for a more friendly contract). I can still take advantage of domain entity functionality, only this time via chatty interaction with the services.

    I’m interested in your per screen use, and how you manage it without resorting to loads of duplication and an array of dto’s that are hard to differentiate.

  4. joeyDotNet says:

    @Ben,
    Well, this is really the first project I’ve started using this approach, but so far it’s working out pretty well. I started to explain it here, but I think I’ll be able to explain it a little better in a separate post (which is in progress).