Leveraging value objects & domain services

Introduction

Over the years I have come to see and also been guilty of not modelling concepts that should be treated as such in the domain your working in and instead what this leads to is 2 primary code smells:

The first manifests itself as values that get passed around together but are always taken by functions as standalone parameters there is usually a breakage of DRY here with knowledge of what the parameters represent scattered around the codebase. The second relates to a refusal to try and apply object thinking and instead procedures are created with no real intent as to where the behaviour should reside and because were in an OOP language they have to live somewhere right? So we end up with badly named classes that just become containers of procedures (and if you’re really unlucky they deal with a whole host of unrelated responsibilities!)

Resolving

So how can we resolve these issues? Well as it turns out we can usually stamp out both by introducing a Value Object that properly represents the concept in our domain by making this first step we can usually start moving behaviour related to this new concept from the *Util class into the actual object here it becomes a much more rich object with it’s own behaviour instead of just being a dumb data holder.

There are however times when certain behaviour cannot just be moved inside the new concept object and for these cases you will probably want to introduce a Domain Service object the difference here between the Util class vs. the Domain Service is that it is specific for a certain operation that you want to perform and as such can be properly named around the current domain your working in.

Example

The example I’m going to show has been a really common scenario I have found while working on various financial systems for a number of years.

In a financial domain you will have a concept of Money it will consist of:

  • Amount
  • Currency

Seems fairly straightforward and it is, however lets look at how I typically see this concept dealt with in code.

public static string FormatMoney(IDictionary<string, int> currencyDecimalPlacesLookup, decimal amount, string currency, bool includeCurrency)
{
    // lookup for decimal places
    // string.Format using amount with found decimal places and currency flag
}

public static string FormatCurrencyDescription(Dictionary<string, string> currencyDescLookup, string currency)
{
    // lookup by currency code
}

public static decimal ConvertGBP(Dictionary<string, decimal> xrates, string currency, decimal amount)
{
   // lookup rate by currency code
   // apply conversion
}

Here is an example of their usage:

string balance = MoneyUtil.FormatMoney(_decimalPlacesLookup, account.PostedBalance, account.CurrencyCode);

string currDesc = MoneyUtil.FormatCurrencyDescription(_currDescLookup, account.CurrencyCode);

decimal inGBP = MoneyUtil.ConvertGBP(_xrateLookup, account.CurrencyCode, account.PostedBalance);

So to start with these probably were just inlined inside one of the calling functions but then someone saw they needed to do the same thing somewhere else and created the MoneyUtil class hooray for reuse! As you could imagine these will then continue to grow and become dumping grounds for any behaviour related to Money, you can already see that unrelated responsibilities are being introduced formatting & currency conversion have no reason to live together, you can also see that the caller is having to manage lookup dictionaries which is another sign of primitive obsession and that modelling concepts are being missed.

As described in the introduction we can see that certain values are being passed around together in this case the amount & currency however we have not captured the intent of these values by introducing a Money object, instead we will introduce the concepts of the domain and see how that changes things:

public class Currency : IEquatable<Currency>
{
	public Currency(string code, int decimalPlaces, string description)
	{
		Code = code;
		DecimalPlaces = decimalPlaces;
		Description = description;
	}

	public string Code { get; private set; }
	public int DecimalPlaces { get; private set; }
	public string Description { get; private set; }
	
	public override string ToString()
	{
		return Code;
	}

// ... emitted rest of implementation
}

First we have the concept of a Currency this may seem like a pointless object however even just doing this step alone would change our signatures for the functions above so that no longer do they just accept a magic string for currency code but instead a properly defined Currency object that already has its information encapsulated in once place.

There a few items to note when creating Value Objects:

  • They are immutable
  • Identity is based off their properties (I have not shown this here but you can see in the full source)
public class Money : IEquatable<Money>
{	
	public Money(decimal amount, Currency currency)
	{
		Amount = amount;
		Currency = currency;
	}

	public decimal Amount { get; private set; }
	public Currency Currency { get; private set; }

// ... emitted rest of implementation

	public override string ToString()
	{
		return string.Format("{0} {1}", Currency, FormatAmount());
	}

	private string FormatAmount()
	{
		decimal val = Amount * (decimal)Math.Pow(10, Currency.DecimalPlaces);
		val = Math.Truncate(val);
		val = val / (decimal)Math.Pow(10, Currency.DecimalPlaces);
		return string.Format("{0:N" + Math.Abs(Currency.DecimalPlaces) + "}", val);
	}
}

We can see that the Money object has to be supplied a Currency at creation and that it now has the smarts to know how to format correctly using the details of its Currency, if you wanted more control over the formatting you could provide an overload to take in a formatter object.

With the changes made above we have nearly made the MoneyUtil class redundant however there is the operation of converting existing Money to Money in another Currency (in this case GBP) this operation is prime example were a Domain Service is a good fit and captures the concept of converting Money from one Currency to another Currency.

First we can define an interface to represent the operation.

public interface ICurrencyConverter
{
    Money ConvertTo(Money from);
}

This captures the operation using the language of the domain and were already getting the benefit of our Money and Currency objects by eliminating primitive obsession were no longer passing strings and decimals but instead fully realised domain concepts.

Next we can implement a CurrencyConverter to convert to a specific Currency.

public class ToCurrencyConverter : ICurrencyConverter
{
	private readonly Currency _toCurrency;
	private readonly IDictionary<Currency, decimal> _rates;

	public ToCurrencyConverter(Currency toCurrency, IDictionary<Currency, decimal> rates)
	{
		_toCurrency = toCurrency;
		_rates = rates;
	}

	public Money ConvertTo(Money from)
	{
		if (!_rates.ContainsKey(from.Currency))
		{
			throw new InvalidOperationException(string.Format("Could not find rate from currency: {0} to: {1}", from.Currency, _toCurrency));
		}

		decimal rate = _rates[from.Currency];
		return new Money(from.Amount * rate, _toCurrency);
	}
}

On creation we provide the converter the Currency we want to convert to and also the rates that should be used, these would typically be populated daily and then cached for faster access although these are concerns way outside of the domain model and it does not concern itself with how these are provided.

With this final piece of the puzzle complete we can now take joy in removing our MoneyUtil class and instead having a richer domain model.

I have published code to go along with this post that can be found here https://github.com/stavinski/joasd-domainconcepts

Can’t we do better than null?

So you want to retrieve an aggregate from a repository (assuming DDD) stored in some data store so you make a call not unlike the following:

Product product = productRepository.FindById(id);

You then go to execute some method on the Product aggregate and boom the dreaded NRE (Null Reference Exception) great, now we can just go to tried and tested !== null check however I want to explore different ways we can actually deal with values that may or may not be present and make this more explicit and give the consumer a better experience.

Is it an exceptional circumstance?

I guess the first question we could ask is would it be considered exceptional that we cannot find the aggregate we are looking for, in the example above we are using the id to find the aggregate which is about as specific as we can get and in most cases the id would have been assigned against a selectable item so not being able to retrieve the aggregate but likely be:

  1. Infrastructure issue in which case you would get an exception thrown at the infrastructure level
  2. The id has been tampered with to make it invalid or non accessible
  3. The aggregate has been removed

Now a case could be made that these are pretty exceptional conditions, however if we change is so that we are trying to retrieve an aggregate based off a natural id for instance a SKU then it becomes a non exceptional circumstance as it could just be that we have not assigned to the SKU to the product or has been done incorrectly.

I also find that your in the same boat with regard to the consumers point of view as the null return but in this case you will get a custom exception thrown at you which is slightly better (checked exceptions in java would make it explicit it could throw).

Return result with output

The next way we could make it more explicit to the caller is by changing the signature to this:

bool FindById(ProductId id, out Product product);

This goes back to the C days if you check out some of the WinAPI you would typically call a function that would return the result of the call and assign a value to a pointer passed in, thankfully the C# is a bit nicer but from a consumer point of view it is explicit but generally not a nice API to expose:

Product product = null;
bool found = productRepository.FindById(id, out product);

Personally I have never liked using out parameters I think mainly due to the declaring of the output parameter(s) before making the call.

Null Object

Another option is to have the repository return a Null Object if it cannot find the aggregate, I don’t think this option would be suitable for a repository as aggregates tend to be treated in much higher regard than optional objects however this strategy can work well in other scenarios where you could provide a default behaving object.

Why returning collections causes no problem

If we look at another method on our Product repository:

IList<Product> FindByCategory(ProductCategoryId productCategoryId);

When we use this method and it doesn’t find any Products for the category id supplied we don’t have the same problem as the FindById instead we just have an empty list (there’s a special place in hell reserved for people who return null out of these type of methods) so our consumer does not need to perform anything differently:

var foundProducts = productRepository.FindByCategory(productCategoryId);
foreach (var product in foundProducts)
{
    // do stuff here
}

The key difference between this signature and the FindById is that the actual products are now housed inside a container (in this case an implementation of IList<Product>) in order to get to the Product we have to go through the container.

This is one area where functional languages have the edge as they don’t have the concept of a null instead you have to be explicit by using a Maybe/Option and the consumer is forced to handle what to do in both cases (this is made easier by pattern matching).

What if we took a similar approach for returning our single Product.

Using a Tuple

The simplest way we could achieve this is by using a Tuple:

Tuple<bool, Product> FindById(ProductId id);

Now we are returned a result that gives us a container in that provides us with more context we can now use this as a consumer like this:

var result = productRepository.FindById(id);
if (result.Item1)
{
    // product was found
}
else
{
    // product not found
}

Now the consumer has a bit more to go on with regard to how the repository behaves and could probably assume that the first item corresponds to whether a Product has been found, as mentioned in the last section functional languages have pattern matching which makes this a bit more explicit, here is an example of what C# could look like if it had pattern matching:

var result = productRepository.FindById(id);
switch (result)
{
    case (false, _):
        // product not found
    case (true, product):
        // product found
}

Query Result

The Tuple approach is a step in the right direction however it’s not very expressive what if  we were to create our own object that represents the results of a query ideally as a consumer we could then use it like this:

QueryResult<Product> result = productRepository.FindById(id);
if (result.HasResult)
{
    var product = result.Result;
    // product found
}
else
{
    // product not found
}

// or if your feeling functional
result.Found(product => // product found);
result.Missing(() => // product not found);

I have shown 2 different API’s depending on the consumers preference, we have taken the approach of returning a container so the consumer must go through this in order to get to the Product, this makes it really explicit on how you deal with the result and no surprises.

I have pushed up a working version of this object to https://github.com/stavinski/joasd-queryresult so feel free to take it and do what you want with it.

log4net FallbackAppender – under the hood

Some Background

I recently put together log4net contrib project up on google code the only item currently up there (though hopefully there should be more stuff from the community up there) is a custom appender I wrote to address the need for having an appender that is clever enough to fallback to other appenders if one fails, this originally came from a forum post of someone wondering how to do it and after some investigation I was that NLog has this built-in.

Investigating how to add it

So my first step was to grab the log4net source and see how I could integrate this appender in, one thing I really didn’t want to do was to change the log4net code and instead allow the appender to be plugged in like you would do normally.

First step was to see how to create an appender that holds other appenders and stumbled across IAppenderAttachable and then the ForwardingAppender which implements it, this interface is what allows you to user the following xml:


      
      

And the configuration makes sure that the appender is populated with the referenced appenders. Looking at the behaviour of the existing ForwardingAppender it gave me a lot of what I was after so I inherited from this.

Hitting the main problem

Now I had the FallbackAppender which got most of it’s behaviour from the ForwardingAppender the next step was to setup the following logic:

  1. Get first appender in the collection
  2. Try and append to it
  3. If succeeded exit
  4. Otherwise try and append to the next appender in the collection
  5. Rinse repeat until one succeeds or all are exhausted

On the face of it this seems to be quite simple, loop the appenders and put a try…catch around the call to Append then have some logic in the catch to use the next appender and repeat, something like this:

while (apppenderQueue.Count > 0)   
{   
    try   
    {   
        var appender = appenderQueue.Dequeue();   
        appender.Append(loggingEvent);   
        break;   
    }   
    catch (Exception thrownException)  
    {  
        // log to internal log about failure 
    }  
}

When I tried this and tested against log4net it didn’t work only the first appender was being appended to if I setup the config incorrectly to simulate an issue.

After some digging the issue became obvious the appenders don’t let exceptions bubble up through the stack and instead log to an IErrorHandler that they get via a property from the AppenderSkeleton object they inherit from and with this being the only way to track errors from appenders I had to then impose a limitation.

Adding the AppenderSkeleton limitation to go forward

With the ErrorHandler property coming from AppenderSkeleton being the only way to discover errors I came to the conclusion that I needed to hook into this property luckily the property can be set, this also imposed the limitation that any of the appenders being referenced had to inherit from AppenderSkeleton in the inheritance tree at some point in order to get access to the ErrorHandler property.

Putting in the hooks

The next step I did was to create my own IErrorHandler that simply recorded if an error occurred, and at appender activation I replace each of the referenced appenders ErrorHandler with that one, now the code can see if an error has been raised for a particular appender and move onto the next one.

Summary

I guess this post demonstrates that even if a third party component doesn’t necessarily provide you with an API that makes extending behaviour easy in this example if log4net appenders let the exception bubble up or the Append method returned a bool whether it succeeded or not, there are still tricks we can use to try and achieve it.

RouteValueDictionary and why we need Hash Literals

When working with ASP.NET MVC you will find quite a lot of code that needs key value pairs, especially for routing and providing html attributes, and in most of these places you will see a trend whereby no Dictionary type is created but instead an anonymous type is used:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = "" }

So how can it take our anonymous type and create a dictionary from it? Well the object that does the work resides in System.Web.Routing and is called RouteValueDictionary (I think this should be called something like AnonymousTypeDictionary and placed somewhere else as it doesn’t really have anything to do with routing and is used in other sections), this object implements IDictionary<string, object> and has an overloaded constructor that takes a plain object type, it then uses reflection to grab the properties associated with the object and uses the property name as the key and the property value as the value.

So when any of the ASP.NET MVC objects want to create a key value pair they simply pass the anonymous type to the RouteValueDictionary object’s constructor:

// routeValues and htmlAttributes come in as object type.

return htmlHelper.ActionLink(linkText, actionName, null, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes));

And voila instant IDictionary<string, object>!

So if this works what’s the problem… well in IMO it’s hack to get round the issue that C# doesn’t have support for hash literals and it would seem I’m not alone, it suffers from a few problems:

  1. Because it uses anonymous types this means the parameter to the method has to be of type object, and from an API point of view that gives us nothing to go as to what needs to be passed in.
  2. It uses reflection to build the key value pairs which takes a performance hit.

For instance take Boo, we could write the following:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    { "controller" = "Home", "action" = "Index", "id" = "" }

Or by using the open compiler wizardry:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    { controller = "Home", action = "Index", id = "" }

Maybe this is asking too much from the compiler and this is as close as were going to get but that would be a shame given the problems above this approach suffers from.

Getting to grips with NHibernate: Stored Procedures Redux

Update: Due to popular demand I have included using stored procedures for insert/update/delete

I hope this post saves someone the amount of time it took me to try and run a stored procedure using NHibernate.

Selecting from a Stored Procedure

Create Stored Procedure

The first step is to create your stored procedure, if we take a basic example:

CREATE PROCEDURE SearchStaff
	(
	@LastName VARCHAR(255) = NULL,
	@FirstName VARCHAR(255) = NULL
	)
AS
	SET NOCOUNT ON

	SELECT s.*
	FROM Staff s
	WHERE (s.LastName LIKE @LastName OR @LastName IS NULL)
	AND (s.FirstName LIKE @FirstName OR @FirstName IS NULL)
	ORDER BY FirstName, LastName

	SET NOCOUNT OFF

Note the SET NOCOUNT ON/SET NOCOUNT OFF

Create a named query

In order for NHibernate to be able to run the stored procedure, we need to create a named query, in our hbm file:


	
	  
	  
	  
	  
	
	exec SearchStaff :LastName, :FirstName

In this example because the stored procedure is actually returning a staff object I set the return to the Staff class, if I was only returning something like an integer value I could use the following:


    
    exec StaffCount :LastName, :FirstName

The name does not need to be the same name as the stored procedure.

Create the NHibernate code

// session set here

IQuery searchQuery = session.GetNamedQuery("StaffSearching")

if (!string.IsNullOrEmpty(LastName))
	searchQuery.SetString("LastName", LastName);
else
    searchQuery.SetString("LastName", null);

if (!string.IsNullOrEmpty(FirstName))
    searchQuery.SetString("FirstName", FirstName);
else
    searchQuery.SetString("FirstName", null);

IList foundStaff = searchQuery.List();

Notice that the stored procedure can deal with or without filtering, so if the fields have not been set we can simply set them to a null value and NHibernate will pass the parameters as a NULL which is what we want.It’s worth noting that the above is quite a simple example and that for the above I would not use a stored procedure and instead just use NHibernates own querying objects. The case were I used a stored procedure was for a paging routine for SQL server 2000.

Using Stored Procedure for Insert, Update & Delete

Create Stored Procedures

CREATE PROCEDURE InsertStaff
	(
	@LastName VARCHAR(255),
	@FirstName VARCHAR(255),
             @EmailAddress VARCHAR(512)
	)
AS
             INSERT INTO Staff
             (
              LastName,
              FirstName,
              EmailAddress
             )
             VALUES
             (
              @LastName,
              @FirstName,
              @Email
             )

Note: SET NOCOUNT is not set for these stored procedures

I’m not going to include the SQL for the update and delete stored procedures as I don’t think it adds any value, and is the easy part.

Update NHibernate XML Mapping

We need to tell NHibernate the SQL we want to execute for our insert/update/delete, we do this inside the class element:


    
      
    
    
    
    

    EXEC InsertStaff ?,?,?
    EXEC UpdateStaff ?,?,?,?
    EXEC DeleteStaff ?

Caveats

  • The last parameter will be the id for the update.
  • The ordering of the parameters is determined by NHibernate, so the best way to find out the ordering would be to view the generated SQL, bit pants but hay ho.

Your code will remain the same, so no changes needed there.

Why does GridView…

…not support inserting a record out of the box? Just seems like something so obvious you would want to do.

Instead you end up having to do something like this where you use a FooterRowTemplate and wire up your own insert call.

Dogfooding with Lightweight Object2Object Mapper

After gettting some feedback about my Object 2 Object Mapper on codeproject I made some amendments over the weekend and wanted to put them into practice, thats when I decided to go down the dogfooding route with the Staff Intranet project being my dog so to speak.

Mapping in the Staff Intranet was handled by having a Mapper object for each mapper permutation each deriving from an IMapper generic interface. So I began by making sure all my tests ran ok then one by one replacing each bit of code that referenced the mappers and instead setup the mappings using a SimpleObjectMapper and registered it into the SimpleObjectMapperContainer, i could then replace the code using the existing mapper to use the registered SimpleObjectMapper, re-run the tests to make sure everything was still expected.

There were a few little areas that needed to be looked at but I was very pleased with the result of making the switch, in the end using the SimpleObjectMapper made the following objects redundant:

And was replaced by the following which is ran inside the Application_Start method:

SimpleObjectMapperContainer.RegisterMapper(new SimpleObjectMapper());
SimpleObjectMapperContainer.RegisterMapper(new SimpleObjectMapper());

SimpleObjectMapperContainer.RegisterMapper(new SimpleObjectMapper()
                                            .Explicit((staff, staffDTO) => staffDTO.LocationId = staff.Location.Id)
                                            .Explicit((staff, staffDTO) => staffDTO.LocationDescription = staff.Location.Value)
                                            .Explicit((staff, staffDTO) => staffDTO.Photo.Data = staff.Photo));

SimpleObjectMapperContainer.RegisterMapper(new SimpleObjectMapper()
                                            .Explicit((staffDTO, staff) =>
                                            {
                                                if ((staffDTO.Photo.SaveOption == PhotoSaveOption.Update) && (staffDTO.Photo.Data != null))
                                                    staff.Photo = staffDTO.Photo.Data;
                                            })
                                            .Explicit((staffDTO, staff) => staff.Location.Id = staffDTO.LocationId));

SimpleObjectMapperContainer.RegisterMapper(new SimpleObjectMapper()
                                            .Explicit((domain, dto) =>
                                            {
                                                foreach (var item in domain.Results)
                                                    dto.AddError(item.ValidationId, item.Message);
                                            }));

With me being on holiday I hope to get the codeproject article updated in the next few days.