Search This Blog

Wednesday, October 20, 2010

Spring.NET and the power of the Dictionary

I stumbled on a technique for simplifying factories (which if you think about, is exactly what Spring.NET's IOC container is) that are context-based.  This is not a new concept but it's worth repeating due to its simplicity and its elegance.

As an example scenario, we have an application that processes about 20 different types of notifications that send out targeted content to subscribers (yes, it's an email application aka SPAM engine).  Each notification can be configured independently of the others in the areas of transformation (the creation of formatted content to send) and transfer (SMTP, DB, MSMQ, etc). 

We arrived at a design that uses Composite, Strategy and Command patterns.  The Composite pattern is applied for Notification Commands (example, a notification that has many sections) and each Notification Command implements the Command Pattern (Execute, etc).  Likewise, Transfers are configured as Strategies (Strategy Pattern) and Composites ( a Transfer Strategy may be 3 physical strategies ie., Send to SMTP, Send to DB and Send to MSMQ). 

To add context, each type of notification has a unique value that traces back to the underlying persistent store.  Notification Type 1 for example, is a "Sales Flyer".

We have a very simple Job controller that is handed a Job (context) and is then asked to process it.  What used to be about 5,000 lines of code (for 20 notifications) has effectively been reduced to about 150 lines of code. 

In our Spring.NET XML registry, we defined our commands and strategies but were then taken aback out HOW we would choose the appropriate command to use to process the Job.  What we arrived at is both simple and rather elegant.

Spring.NET registries can store much more than templates for objects.  They can also store dictionaries.  In our case, we chose to store a dictionary of commands.  The dictionary's key refers to the unique identifier for each type of job and the value is the id of the command to use.  When the controller is activated and the job context passed, we reach into the dictionary (served up as a dependency property to the controller) and then ask the repository for the ICommand by Id which is retrieved from the dictionary. 

Code can be shared if anyone is interested although I'm fairly positive this is not an original idea and to some may be more along the lines of  "we already do this".

No comments:

Post a Comment