Monthly Archives: April 2009

Move Over ASP.NET WebForms and MVC!

This seems to be a hot topic right now.  Everyone is talking about the decision to switch from ASP.NET WebForms to the new ASP.NET MVC.  It can be a tough decision, but fortunately there is an alternative.  Classic ASP.

I cast my vote for moving back to the well-established Classic ASP framework.  I cast my vote for debugging using Response.Write and zero separation between code and markup.  I cast my vote for the coolest. language. ever.  VBScript.

We as a community should recommend, nay, demand, the move back to Classic ASP.  By doing so, we will watch our productivity soar!

 

 

 

DISCLAIMER: Not valid in CA, NY, TX, or Possum Lake.  Side effects may include nausea, vomiting, suicidal tendencies, or unexplained depression.  Discontinue immediately if you experience any of these symptoms.  May cause sudden losses in productivity, increase in development time, or exponential increase in bugs.  We are not liable for loss of employment due to forgetting more valuable skills.

All Your Repositories Are Belong To Us

Who would have thought that the Repository Pattern could become a battleground?  I always thought it was pretty straightforward—at least, that’s how I felt when I first read Domain-Driven Design a few years ago.

While I could immediately see the benefits of using a repository, there were a few things that really bothered me as I started implementing the pattern that I could never fully reconcile:

  1. How do we best query the repository to find the particular aggregates that we care about?
  2. How do we handle UI concerns such as paging within the repository?
  3. Does the repository even care about UI concerns?
  4. How do we display domain objects to the UI (this is only slightly related to the repository pattern).
  5. How do we modify our domain objects to support lazy loading?

When I first stumbled upon Greg Young’s solution of Command Query Separation as an architectural pattern, I immediately knew that this was the way to go.  It was as though someone turned on a light bulb—a really big light bulb.  It was an idea whose time had come.  Paradigm shifts are like that.  The bigger the attachment to the old philosophy, the bigger the “ah ha!” when you finally see it in a new light.

CQS instantly solved all of my problems and questions with repositories.  The answer is simple—you don’t query the repository to perform searches.  Instead, you load specific aggregates from the repository by their identity.  Further, paging is purely a UI concern, therefore we query a completely different data source–or at least access the data source through another mechanism.  Queries and searches are performed against this alternate mechanism as well.  Lastly we don’t display our domain objects.  We display simple DTOs that have been queried through this alternate data access mechanism.

With all of this as introduction, it has been very amusing and informative to see Oren and Greg battle it out regarding repositories in general:

All of the posts are worth reading several times.  Summing them up in a single phrase doesn’t do them justice.  Further, the summary I gave is a bit arbitrary as it may not accurately express the main concepts of each post.

Being a huge fan of CQS, I’m going to have to go with Greg on this one.  No surprises there.  Even so, I find Oren’s blog inspiring to read.  The frequency of his posts make me wonder if he does anything else, but the amount of tested code he cranks out is astounding.  In frequency of blog posts, Oren wins hands down.

To conclude, I see this debate as a healthy thing in the DDD community and the ALT.NET community.

DDDD: Aggregate Versioning & Persistence Schema

In a previous post, I talked about a possible relational database schema for event storage.  I also discussed the idea behind aggregate versioning in a relational store.  In this post, I’d like to talk about storage in a non-relational persistence medium, such as CouchDB, HyperTable, or even the file system.

One of the reasons behind the “last_snapshot_seq” column in the relational schema is that is helps determine the point at which to start loading events from the database.  Because, by definition, a relational set is unordered, we needed a way to retrieve all events that have occurred since (and including) the last snapshot event in one fell swoop.

Using a non-relational model changes things slightly.  We can start to treat the events stored for an aggregate as a collection accessible by an index.  Using this mechanism, we start evaluating the events one by one beginning with the one that has most-recently occurred.  For example, as we get the events, if the most recent event is not a snapshot message, we put it onto a temporary stack.  We then read the next event.  If that event is not a snapshot message, we push it on the stack on top of the previously retrieved message.  We continue and read the next message.  If that event is a snapshot, we run it through the aggregate, pop the stack and run the next event through the aggregate root and so forth.  This has the effect of bringing our aggregate to the last known state.

As you can see, we’re working with events one at a time from the persistence engine.  Because of this, we need to know the sequence number of the most recent event to be processed by the aggregate, which allows us to know the point at which to start loading events.  This is where the storage for the aggregate version comes into play.  In Greg’s devTeach video (at 39:45), he mentions persisting the version to the persistence mechanism.

The reason that it’s important to store this value is so that we know the sequence number of the event at which to start retrieving the event messages from the store.

Granted the event store could be implemented any number of ways.  In thinking about it, you could still potentially store the last snapshot message sequence and load events forward (using a queue) or you could read from the end and move to the beginning of the storage (using a stack).  The important thing is that you know the point at which to begin loading an event, that they are loaded in order, AND that you know the version number of the aggregate for the next message when you’re pushing events to the persistence engine.

DDD: Strategic Design: Core, Supporting, and Generic Subdomains

I have been re-reading Domain-Driven Design after watching several InfoQ presentations given by Eric Evans as well as an interview of Eric at QCon in San Francisco in 2008.  There were several core concepts that really stuck out to me as I was watching these in one sitting.

One of the key points that really stuck out to me for some reason was the concepts surrounding “strategic design” and the need to break down that design into parts.  Obviously breaking things down is critical but the way in which they’re broken down is important.

Generic Subdomain

When you’re writing or re-writing an enterprise application, there are going to be parts of the system that facilitate the business, but are not core to the business.  For example, in most businesses there is a concept of invoicing—sending bills to customers.  While this is a critical business concept, it is not “core” to the business.

In general, these types of pieces can be purchased from a vendor or outsourced (I can’t believe I just said that) and then wrapped in such a way to communicate with the rest of the enterprise as necessary.

Supporting Subdomain

These types of pieces are also necessary because they help perform ancillary or, well, supporting functions related directly to what the business does.  In these cases, high-quality code and perfectly designed structure are not necessary.  You could get by with assigning more inexperienced developers or even, dare I say, outsourcing these pieces.

Just be sure that these concepts do not bleed into your core domain—you want to maintain a rigid separation with a context map to keep separate things separate.

Core Domain

Eric asks several questions to help us identity which parts are core to the domain:

  1. What makes the system worth writing?
  2. Why not buy it off the shelf?
  3. Why not outsource it?

The core domain is so critical and fundamental to the business that it gives you a competitive advantage and is a foundational concept behind the business.

This is the domain that you want your most experienced people working on, instead of having them work complex (and fun) technical or infrastructure problems.

As Eric puts it into numbers, the Core domain should deliver about 20% of the total value of the entire system, be about 5% of the code base, and take about 80% of the effort.

DDDD: Double Dispatch

I just finished watching David Laribee’s devTeach video.  Towards the middle of the presentation he started talking about domain services and how we can use double dispatching to provide a service to a domain entity.  By doing this, we gain the ability for the domain object to call the domain service—without injecting it during construction.  This, in turn, facilitates variability because we can provide different implementations of the service which may or may not access other external services or state—all without leaking infrastructure concepts into the domain.

Using double dispatch works great in traditional DDD, where you simply pass the domain service to the entity as part of a call to a method perform some computation.  But what about DDDD?

In typical DDDD, we have a MapMessageToAggregateRootHandler that loads the aggregate, casts it to IConsume (T is a Message) and passes the message into the aggregate for handling.  This doesn’t work with double dispatch.

The only other possibility that I can see, which still avoids injection, is to create different message handlers for those messages that require double dispatch capabilities and to and expose domain-specific methods on the aggregate root rather than a generic Consume method.  Then the handler could call the method, provide the message and corresponding domain service—or it could simply provide the needed parameters from the message along with the service.

UPDATE: There is another option.  The aggregate root could explicitly implement an interface like IConsume.  Then we could have another application service that maps a specific message along with a domain service to the aggregate root retrieved from a repository.  The types of messages that require this new handler could all easily be registered in the DI configuration.  Granted, I haven’t fully analyzed the architectural implications of such an interface, but from an implementation perspective, it should work.