.net and other musings

Ben Lovell, an agile developer living in the UK.

Category: DDD

Incremental development with Monorail: Part Five

Welcome back. In this post I’ll be getting our tests passing again and cleaning things up a little. We left off with a failing integration test:

42

I suspect this is due to the IBlogPostMapper dependency we introduced to our BlogPostService not being handled by the container. If we run in the browser we can confirm this is in fact true:

As we’ve yet to implement our IBlogPostMapper we must go ahead and do this before we can add the container configuration to pass our integration test. Lets bust out a test and get things rolling:

43

We have a few blanks to fill in in order to get this to compile and run:

  1. Make the DTO’s properties virtual so we can mock them. This is in preference to extracting an interface.
  2. Implement IBlogPostMapper.
  3. Add the necessary properties to the IBlogPost interface.

Lets go ahead and do this now:

44

IBlogPostMapper minimal implementation:

45 

The necessary modifications to IBlogPost:

46

Now we can compile and run our test:

47

Our BlogPostMapper implementation is throwing an exception so lets go back and take another step to try and pass our test:

48

BlogPost:

49

I’m pretty certain we’ve done enough to pass our test now. Lets have a go:

50

OK now lets focus on the full suite:

51

Our integration test is still bombing but as we’ve got a mapper now, we can go ahead and wire up our Windsor configuration and get things moving again:

52

We’ve added another configuration file: mapper.config and referenced this from the web.config. We shouldn’t need to do any more than this so lets run our full test suite:

53

Our full suite is passing now. Not bad for 5 minutes work! As usual the latest changes are checked in to the Google code project hosted here.

Now we have a full passing suite, in our next edition I’ll be moving down into the persistence and also incorporating a few modifications from Hammett. Stay tuned!

Advertisements

Incremental development with Monorail: Part Four

We finished up in the last instalment by moving down a layer into our newly introduced BlogPostService. Our tests are passing yet our application is still pretty lacking in the actual functionality department. To move things on a stage further we need to:

  1. Map from the AddPostRequestDto to our actual BlogPost aggregate root.
  2. Validate the BlogPost.
  3. Persist our new BlogPost.

We need to write another test to flesh out the interaction between our service and something that can map from the DTO to our BlogPost:

37

We’re now expecting the BlogPostService to accept the mapper in its constructor, and defining an interaction between the service and the mapper. Before we can get this to compile we need to make a few more changes to our test fixture:

37

We’ve modified an existing test to allow for our new dependency and performed some setup tasks. We’ve introduced the IBlogPostMapper and IBlogPost interfaces by way of our test. Running the test causes the compiler to choke so lets go ahead and implement what we need to pass the tests:

38

39

40

Lets go ahead and run our BlogPostServiceFixture tests:

41

Righteo, that went well. For the sake of completeness lets run our full test suite:

42

The integration test is failing as we’ve yet to wire up the BlogPostService dependencies in the container. Before we can do this we need to drive out the interfaces we’ve introduced. We’ll do that in the next post.

Incremental development with Monorail: Part Three

Part One
Part Two

In the last instalment we finished up with a suite of passing tests. However, we’ve yet to produce anything remotely usable so lets continue by reaching down further and driving out our services/persistence. We’ll start by writing the following test:

23

We’ve meddled with our test setup a little to introduce the MockRepository for mocking out our PostController’s new dependency on the IBlogPostService. Our test now calls the AddPost method on our service interface and sets up the resulting AddPostResponseDto. Running the test produces a bunch of compiler whinging so we best implement the newly introduced bits:

24

25 

26

These are the only changes and additions we’ve made in order for the tests to compile and run. Running our test now produces the following result:

27

As we’ve yet to modify the PostController.Save(…) call to include a call the newly introduced IBlogPostService dependency. Lets go ahead and do this now:

28

We’ve now included the call to our newly introduced service and we set the responseMessage if the response is signaled as successful. Lets run our test now:

29

It works, ship it! Actually no, again we’re pretty low on actual functionality right now. Remember we’ve yet to actually drive out any implementation of the IBlogPostService interface as yet and I expect that the acceptance test will fail horribly since we didn’t wire up the necessary container configuration either. Lets go ahead and run the whole test suite and see what gives:

30

In the brief moments the browser appears during the test we can see the following:

31

Hmm, as I predicted earlier our application fails to run due to the lack of proper container configuration. Before we can do this we need to implement the IBlogPostService interface somewhere. We need to write a failing test to begin our foray into the implementation of a BlogPostService:

32

Lets create the BlogPostService only performing the steps necessary to pass the test above:

33

Run the test:

34

Now we have a working BlogPostService we can now wire up our container configuration to pass the acceptance test:

35

Now running the full suite of tests produces the following:

36

Our tests pass!

That’s it for this post. I’ve checked in the latest changes to the repository. In the next post we’ll continue our efforts and begin to implement validation on our screen-bound DTO’s.

Google code hosted project: http://code.google.com/p/mr-blogengine/

Front-end DTO’s

An interesting discussion was brought up in one of the ALT.NET groups regarding the use of DTO’s in the presentation layer that I had to chime in on.

I’m a strong advocate of message passing from the UI to your services for several reasons:

  1. Test driving from the top-down is my favoured approach when developing web applications. I’ll start by writing a failing test for my controller (you should know by now I use Monorail ;)). Then I’ll stub out any dependencies, these usually being service interfaces which accept and return simple DTO’s with absolutely no behaviour. Stubbing out the services allows you to return dummy data very early on in your development. The nice thing about this approach is you can get a working UI together very quickly and then drive out the development of each layer until you hit your domain model. From which point you can then wire-up your real service and repository implementations and satisfy your acceptance tests end-to-end. Now I’m not suggesting that this approach isn’t possible without DTO’s but it makes it a heck lot easier in my experience.
  2. DDD aggregates by their very nature are composed of behaviours you don’t want to pass into your UI. Using DTO’s for binding into your UI keeps things nice and lightweight. Cohesion is high as the DTO’s are created for a very specific purpose, usually to satisfy a particular screen or UI workflow.
  3. I had made the rather nebulous statement that the use of DTO’s insulates your UI against changes in your domain model. Quite rightly somebody replied saying that this was all relative and there are many means to insulate against change. Of course, I wholeheartedly agree but in my defence I was replying to the OP from my iPhone. Now for me to explain this a little… Unless you’re using query projections (a la NHibernate) you’ll be mapping from your domain entities to specific DTO’s using some kind of mapper class. Your mapper probably depends on the interfaces of your particular domain entities and the implementation of your DTO’s. I say implementation as I drive out the mapping using state-based testing, which of course makes perfect sense when mapping from one state to another! Using DTO’s means our controller has a nice seam between itself and the services through their interfaces thus the controller (read: UI) has no knowledge of the domain model at all. Any changes to the domain model are catered for by changing the mapper specific to the affected messages. I won’t get into versioning messages, mainly because I haven’t got the time or inclination 🙂
  4. I’ve always thought (and I read this somewhere I think, but can’t remember where) that a sign of a well designed architecture, among other things of course, is the ability to replace the UI and have everything function correctly. Now it was probably more poetic than that but essentially what this means is your UI should have absolutely zero dependencies on anything below your service interfaces. Using DTO’s and message passing means the only work your controllers are doing is scraping the request, passing your message to a service and binding the response. I’ve demonstrated this in systems I’ve developed by providing an API (which can be considered another UI if you squint a little and look sideways) which is comprised of exactly the same service calls and DTO’s my web UI is using.
  5. My last point isn’t specifically tied to the use of DTO’s but more based around messaging architecture in general… What this gives me from the very beginning (i.e. the first test) is a nice basis for distributing my architecture. Our services can be hosted on an application server separately from our web application  or preferably located transparently via a message bus which brings in a whole heap of nice side-effects…

So in summary you can see I’m a big fan of the domain model in my services, mapping to and from DTO’s in my UI. What is your favoured approach?

Improving Applications Design with a Rich Domain Model

Take a look at this talk on DDD given during Spring 2007 by Chris Richardson for a heads-up. Its probably the most concise I’ve seen on the topic so far.

Have a look.