Tuesday, October 07, 2008

Querying with Castle ActiveRecord

We recently started a project where I decided to use Castle’s ActiveRecord. On previous projects I had used NHibernate with a repository pattern, but for multiple reasons the active record pattern is more appropriate in this project.

One of the lowest hanging fruits of ActiveRecord is its abstraction from the NHibernate mapping files. Combine that with inheriting your domain objects from the ActiveRecordBase class and in no time you’re good to go with an object-oriented domain model that can easily be persisted to a relational database.

So far so good. But not too long into the project, you’ll find that need to start querying your domain model and then what do you do? Unfortunately, the query-side of Castle’s ActiveRecord is rather poorly documented. It’s kind of limited to this one page. For me that wasn’t enough to grasp the ideas behind it or give me a good feeling of what can be achieved with it. For example: there’s an ActiveRecordQuery class. What do I do with it? Do I inherit from it, like with ActiveRecordBase. And if so, what do I get? And what part is Castle specific and what part NHibernate specific?

Some sniffing on the internet did not reveal a whole lot more and that’s why I decided to open up the source code itself and find out for myself. Here I my findings for the most recent framework version at the time of this writing: 1.0.3 (RC3).

What does it add?

The query-side of Castle is a bit different from the basic active record side of the framework. On the latter side, things mainly evolve around the benefits you get from the ActiveRecordBase class by inheriting from it. There is no such thing for the query-side, which is actually a rather thin wrapper around the default NHibernate query functionality. It’s almost so thin, that you wonder why you should actually bother with the query-side of ActiveRecord. And there seems to be only one real compelling reason: the fact that it abstracts away from the NHibernate session. After all, the ActiveRecordBase hides the session as well and you wouldn’t really want to have to worry about an NHibernate session just to get your queries to work.

So what does the query-side of the framework offer? Well, actually a number of helper classes that aid in composing the right type of NHibernate query. It simply works as follows:

  1. instantiate a query helper object that suits the type of query you want to perform
  2. set all the necessary query properties on the query helper object
  3. get the query result by executing the query

It’s in the latter case that we see that there are two generations of query helper classes in the framework:

Generation 1 classes whose instances need to be passed into an ExecuteQuery() operation on an instance of an ActiveRecordBase child class; these are:

  • HQLBasedQuery
  • SimpleQuery
  • ScalarQuery
  • ActiveRecordCriteriaQuery
  • CountQuery

Generation 2 classes that have their own public Execute() operation; these are:

  • SimpleQuery<T>
  • ScalarQuery<T>
  • ActiveRecordMultiQuery
  • ProjectionQuery<T,R>
  • ProjectionQuery<T>
  • ScalarProjectionQuery<T,R>

I’m not sure why the two generations exist, but I’m guessing this is due to architectural evolution.

The basics

First a quick tour of the basics.

ActiveRecordBaseQuery

IActiveRecordQuery

The mother of all query helper objects is the IActiveRecordQuery interface class. Primarily this establishes that each query can be executed as long as you pass in a NHibernate session object. This is done through the operation Execute(ISession).

Additionally it offers the RootType property, which returns the target type of the query.

IActiveRecordQuery<T>

Inherits from IActiveRecordQuery and is identical, with the exception that the Execute operation returns type T instead of an anonymous object.

ActiveRecordBaseQuery


This abstract class reroutes the IActiveRecordQuery’s Execute(ISession) operation to an InternalExecute(ISession) operation, which only ActiveRecord classes can get at. Furthermore it offers the hook to a query logger. Anyway, there’s not so much interesting things going on in this class. Things start to get interesting with the first real query helper class you can actually use: the HQLBasedQuery.

HQLBasedQuery

HQLBasedQuery

This is the helper class helps you to compose an NHibernate HQL query. Basically, an HQL query consists of a number of elements:

  • The root type
  • The actual query string
  • The list of parameters passed into the query string
  • A specification of the result range (start element and number of elements to be returned)

The HQLBasedQuery offers several constructors to set up your query with one simple statement. Part of these constructors in a QueryLanguage parameter, which allows you to specify it a query is an HQL (default) or SQL query.

The constructors allow to pass in parameters in a sequential fashion. However, NHibernate also supports named parameters. These name-value pairs need to be set separately with the SetParameter or SetParameterList operations.

So what does this class offer you? Well, next to the abstraction from the ISession, it offers you a different query building syntax. Here’s a quick comparison.

Using the HQLBasedQuery:
HqlBasedQuery q = new HqlBasedQuery(typeof(Cat), "from Cat where Name like ?", "Fritz%");
Object result = Cat.ExecuteQuery(q);
Using NHibernate:
ISession session = ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof(Cat));
Object result = session.CreateQuery("from Cat where Name like ?").SetParameter(0, "Fritz%").List();

As you can see, the hardest part in the NHibernate example is getting to the session object. The actual query execution is actually not all that different.

SimpleQuery and SimpleQuery<T>


clip_image004

The SimpleQuery class does exactly the same as the HQLBasedQuery, with the exception that the Execute(ISession) operation is now explicitly cast to a return type defined in the constructor or - if a return type is not specified - to root type.

With SimpleQuery<T> the exact same thing can be established as with SimpleQuery, only the return type is now T. Firthermore, since this is a generation 2 class it offers its own public Execute() operation. Great! So from .NET 2.0 and up, I’d use this over the non-generic type anytime.

ScalarQuery and ScalarQuery<T>


clip_image006

Just like SimpleQuery, this class does exactly the same as HQLBasedQuery, with the exception that it returns a single instance by applying the UniqueResult() operation on the query result. Strangely enough, there is no constructor that allows you to specify a return type, like we’ve seen for SimpleQuery. Then again these are .NET 2.0 and up days an so…

… we’d probably rather like to use ScalarQuery<T>, since it does return a strongly typed result and offers its own Execute() operation.

ActiveRecordCriteriaQuery


clip_image008

Strangely enough, this class inherits from HQLBasedQuery instead of ActiveRecordBaseQuery. It accepts a criteria array (each of type ICriterion) or a DetachedCriteria structure. No additional query modifiers (like parameters or result ranges) are supported in this class: if you need them, you should make them part of the passed in criteria.


There is one benefit this class gains from inheriting form HQLBasedQuery: if no criteria are passed in at all, an empty HQL query is executed upon execution, thus retuning all objects of the target type.

In essence this object gives you a slightly different syntax for defining and executing criteria-based queries. Here’s a syntax comparison.

Using the ActiveRecordCriteriaQuery:
ICriterion[] criteria = { Expression.Like("Name", "Fritz%") };
ActiveRecordCriteriaQuery q = new ActiveRecordCriteriaQuery(typeof(Cat), criteria );
Object result = Cat.ExecuteQuery(q);
Using NHibernate:
ISession session = ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof(Cat));
Object result = session.CreateCriteria(typeof(Cat)).Add(Expression.Like("Name", "Fritz%")).List();

Hmmm… I’m not sure why I’d want to use the ActiveRecordCriteriaQuery instead of the NHibernate syntax. The latter seems less verbose.

And then I guess I would have expected an ActiveRecordCriteriaQuery<T> (along with its own Execute() operation), but unfortunately this does not exists. I’m not sure why.

CountQuery


clip_image010

This class creates a special HQLBasedQuery, namely one that executes a COUNT query. There are three constructors that allow us to specify the COUNT selection criteria:


  • One with a HQL string based filter and accompanying optional parameters. The filter string needs to be the part that you’ll find in the WHERE clause of the HQL query “SELECT COUNT(*) FROM TargetType WHERE <filter>“.
  • One with a set of NHibernate criteria of type ICriterion
  • One with a set of NHibernate criteria of type DetachedCritera
  • One without any selection criteria, which simply counts all the instances of the passed in target type.

When executed, the query returns an int32.

ActiveRecordMultiQuery


clip_image012

NHibernate offers MultiQuery functionality, which allows you to compile multiple queries and fire them off to the server in one call. The ActiveRecordMultiQuery is there to allow you to compose such a MultiQuery using ActiveRecodBaseQuery child classes. Note, however, that only non-criteria based queries are supported. If you use an ActiveRecordCriteriaQuery or a CountQuery, the ActiveRecordMultiQuery will throw an exception upon execution.

This class is actually a bit shaky in this version of the Castle framework. As you can see the Execite and Enumerate operations expose an NHibernate session unlike all the other classes. Furthermore, the Enumerate operation is not implemented and will throw an exception if you try to execute it. Personally I think this class it the weakest link in the bunch.


ProjectionQuery<ARType, TResultItem>


clip_image014

The projection query is the latest fashion in the framework and the result of great work by Ayende Rahien. He has taken some time to demonstrate the features of this query in a blog post or two.

The “latest fashion” exposes itself by the fact that:


  • better use of generics: both he root type and the return type are specified as generics
  • the use of the pipes and filters pattern for the SetRange operation, which allows you to apply a SetRange to the ProjectionQuery without altering the return type
  • the public Execute operation

Actually, with this new fashion, one could even consider this class to be the first of an even newer third generation of query helper classes in the framework. What does strike me as odd is the exposure of NHibernate’s session in the Enumerate operation.

Upon execution of the query, an internal NHibernate criteria object is instantiated to which:


  1. the list of projections with which the class is initialized are applied using the SetProjection() operation
  2. the SetResultTransformer is applied to transform the result to the TRseultItem type
  3. the array of NHibernate Order expressions is applied, using the AddOrder for each entry. This allows you to indicate by which properties the result should be ordered.

ProjectionQuery<ARType>


Is exactly the same as ProjectionQuery, with the exception that the result is an object array instead of an IList<TResultItem>.

ScalarProjectionQuery<ARType, TResult>


Is identical to ProjectionQuery, with the exception that the result is a single TResultItem instead of an IList<TResultItem>, by applying the UniqueResult<TResult>() operation to the query result.

Conclusion


I think the exploration of the query-side of Castle’s ActiveRecord framework was well worth the effort to get a grasp of what its all about. I was a bit surprised to find that it is actually as thin as it is. Which leads me to question if it worth the hassle to learn the new query syntax imposed upon you by the classes’ API’s. This is especially bothersome, since:


  1. the API’s are poorly documented
  2. the API’s are inconsistent, not only across the generations, but also within the generations

The first issue I hope to have solved somewhat with this blog post, by giving some insight of how these classes relate to the NHibernate constructs, that are far better documented. The latter is hard to solve. The most obvious reason for this being backward compatibility.

These are all compelling reasons for me to consider sticking with basic NHibernate queries. I’m thinking it is worth the extra overhead of retrieving the right NHibernate session in order to execute a query. This could easily be established by creating an ActiveRecordHelper-like class with a GetSession(RootType) operation. Once this is implemented, the query is actually rather straightforward and uses regualr NHibernate syntax, e.g.:

Object result = ActiveRecordHelper.GetSession(Cat).CreateCriteria(typeof(Cat)).Add(Expression.Like("Name", "Fritz%")).List();

Anyway, I'm sure I've overlooked a thing or two, so your thoughts and comments on this are more than welcome!

Thursday, August 21, 2008

New money(.cs)

Version 2

So, right after my first post, I quickly discovered I had a bit of polishing up to do of my first money class. Thanks to a few pointers of "fellow inventor" Codekaizen, I read up on the theory of doing arithmetic with money and I made a few changes to the first implementations. Nothing drastic, but significant enough for me to publish this new version.

Arithmetic

On the arithmetic front, the follow I've reworked the division and multiplication operations. Outcomes are not rounded to the number of significant decimal digits anymore. The rounding is now left to the user. For this I've introduced the new Round() operation. When requesting a string representation of a money object, the amount is rounded automatically.

Furthermore, I reconsidered the use of Decimal (being a floating point type) for the representation of the actual amount. I decided to stick with it. There are a couple of things to note in that context:

  1. A Decimal can hold up to (and even a bit more than) 28 digits => this is more than enough for 98% or more of the .NET applications.
  2. It maps cleanly to decimal types supported by most important databases, thus making table inspection a breeze.
  3. One should be aware of how the floating point behaviour of the Decimal type works. Simply put: a decimal value is a sign bit, 1 to 28 digits and a number indicating the position of the decimal separator.
  4. One should also be aware that doing arithmetic with numbers that are on the extreme ends of he scale can cause loss of precision. E.g. adding 10 to 10^-28 (the smallest positive number) would require 29 digits to represent the outcome correctly, but since we only have 28 to spare, the least significant digit will be left out of the result. In that case, the result is 10.
  5. The "simple alternative" to using a Decimal is using two Int64's: one for the part in front of the decimal separator and one for the part behind it. However, that still gives us a maximum precision of 28 digits and it maps rather poorly to the database. I'd say that if one wants a real alternative to a Decimal, one should go all the way and support the extensive requirements specified in this article by IBM, which indicates a theoretical need for a precision of 2191 digits. We would need a .NET equivalent of Java's BigDecimal for that.

General refactoring

There are three general refactorings I have done:

  1. The CurrencyRepository is now completely static
  2. I made the Money class a real "value object" by making the CurrencyCode and Amount properties read-only.
  3. I completed the list of type converters.

Roundup

That concludes version 2 of this Money class implementation. I'm planning on at least one more release, in which the currencies also contain the unicodes for the currency symbols. That should make displaying those "exotic" (excuse my blatant European perspective) currency symbols easier to display (e.g. in HTML).

Download the C# Money implementation v2 here

I hope this implementation is useful to some of you. I'm always delighted to hear your feedback.

Thursday, July 24, 2008

Making Money with C#

Introduction

So my next .NET project started and sure enough, there was the requirement again to support international customers. Now, most of the systems I work on have quite a bit of financial functionality in them and therefore the handling of money is an important aspect. I have found that most developers like to take the simple approach to handling money, supporting only a single currency by solely using decimal type to store an amount and not explicitly naming the currency. Instead the currency is first made explicit when it is presented on a user interface, adding a currency symbol as it is stored in the “active culture info” (which generally means: the server’s culture settings).

I don’t know about you, but if some system administered some amount of my money, I would be very worried if it simply stored: 1,000,000. Especially if my money were in Euro and the system would be a web system running in the US. Chances are, the system’s implicit currency is USD and the current difference between USD 1,000,000 and EUR 1,000,000 is currently about USD 476,500, which is enough to give me quite big headache! ;)

I think we can all agree that when there is a hint that our system might be confronted with cross-border business, it is a very good architectural practice to store money not simply as a number, but also with the appropriate unit. Martin Fowler has already suggested this long ago (1996) in his book Analysis Patterns, where he discussed the Money analysis pattern to be a specialized version of the Quantity analysis pattern. In his Patterns of Enterprise Application Architecture he revisits the Money pattern with several code samples. So the most ground breaking work has been done long ago already.

What is there now?

There are different angles to look at money representations:

  1. From an administrative point of view (as discussed above), recording and computing monetary amounts along with the correct currency;
  2. From a presentation point of view, describing the way a monetary value is displayed;
  3. From a geographical point of view, listing what currencies are used in what countries.

In .NET, Microsoft has supplied us with facilities for the last two angles with the CultureInfo and NumberInfo classes. Amazingly, the first angle is completely ignored, even though that is what’s needed for solid financial business functionality.

Despite of the work of people like Martin Fowler, it seems there are not too many people who care about the administration aspect of money in the .NET space. At least, that’s the feeling I get when I set out to search for C# Money implementations. That yields one fairly decent implementation by Jason Hunt. Unfortunately, Jason relies on the presentation-related CultureInfo class to store currency information. I think that it is unnecessarily complicated, since it forces me to instantiate “1,000 of that currency they use in the US” instead of instantiating “1,000 USD”.

What do we need?

As far as I can see now, we need to be able to do the following with a money representation:

  • Store monetary amounts as an amount together its currency code.
  • Get a string representation of the monetary amount, dependent on how the user is accustomed to see currencies and numbers. Note that this means that a even though USD is an American currency, a Dutch user would not expect to see the American formatting rules applied to a USD amount, but instead the Dutch formatting rules.

The design

Basic properties

The basics of the Money class are straightforward: we need a property to hold the monetary amount and one to hold the currency of that amount.

public sealed class Money : IEquatable<Money>, IComparable, IComparable<Money>
{
    private CurrencyCodeKind _currencyCode;
    private decimal _amount; 
The CurencyCodeKind type shown in the listing above is an enumeration. The names of the enumerated values are the ISO 4217 currency codes. This allows us to store any monetary amount, independent of culture or presentation standards. For the amount itself, we use a decimal type, generally regarded as best practice for storing monetary amounts. This can hold values from -10 Sextillion to 79 Sextillion (Sextillion = 10^15 Billion) (http://www.statman.info/conversions/number_scales.html), assuming we use a maximum of 3 significant decimal digits. In short: this is more than enough... even for Zimbabwe, that currently has bills up 100 Billion Zimbabwe Dollars!

Here's a snippet of the CurrencyCodeKind enumeration:

public enum CurrencyCodeKind
{
    AED = 784,
    AFN = 971,
    ALL = 8,
    AMD = 51,
    ANG = 532,
    ...
} 
Note that for the indexing values, we use the related ISO 4217 numeric codes. The reason not to use the default incremental numbering scheme for this enumeration, is rather practical: when storing money objects to a relational database, the numeric value of the currency code will get stored. If we inspect a table with Money objects later, it is very convenient to have these ISO 4217 numeric codes show up instead of application-specific numbers.

The same argument holds for the use of the decimal type to store the actual amount: Fowler has shown implementation examples just using (big) integers, which means that in order to know what the right amount is, you’ll always need the application to position the decimal separator correctly. I find that a little too brittle for information that’s that important, hence I choose to go with a decimal datatype that also has an exactly matching representation on database level.

The inner workings

When working with a Money object, we’ll eventually need to know more about its currency than just its ISO code. More specifically we’ll need to know:

  1. The number of significant decimal digits, needed for correct calculations and rounding
  2. The currency symbol for display purposes
  3. The rounding type, needed for rounding of calculation results (discussed later)
  4. The name of the currency (maybe not necessary, but still convenient
I’ve created a Currency class to hold this information for a currency. Here are its properties:
internal class Currency
{
    public CurrencyCodeKind CurrencyCode { get; private set; }
    public string EnglishName { get; private set; }
    public string Symbol { get; private set; }
    public int SignificantDecimalDigits { get; private set; }
    public CurrencyRoundingKind RoundingType { get; private set; }
These Currency class properties are vital for the logic in the Money class. Therefore it is convenient to have a Money object hold a reference to the Currency object that is represented by the Money object's currency code. So let's have some additional private properties on the Money class to achieve this:
public sealed class Money : IEquatable<Money>, IComparable, IComparable<Money>
{
    #region Properties
    public CurrencyCodeKind CurrencyCode { get; set; }
    public decimal Amount { get; set; }
 
    private Currency _currency;
    private CurrencyRepository _currencyRepository = new CurrencyRepository();
    
    private static int[] _cents = new int[] { 1, 10, 100, 1000 };
    #endregion
In order to keep the CurrencyCode and _currency in sync, the currency object reference is set in all places where the currency code can be set, which is in de constructors:

// Initialize a new money with an explicit currency code
public Money(CurrencyCodeKind currencyCode, decimal amount)
{
    if (_currencyRepository.Exists(currencyCode))
    {
        CurrencyCode = currencyCode;
        Amount = amount;
        _currency = _currencyRepository.Get(CurrencyCode);
    }
    else
    {
        throw new InvalidOperationException("Currency code unknown.");
    }
} 
 
// Initialize a new money with the currency code
// held in the passed in CultureInfo.
public Money(CultureInfo cultureInfo, decimal amount)
{
    CurrencyCodeKind currencyCode;
    try
    {
        currencyCode = (CurrencyCodeKind)Enum.Parse(typeof(CurrencyCodeKind), (new RegionInfo(cultureInfo.LCID)).ISOCurrencySymbol);
    }
    catch (Exception)
    {
        throw new InvalidOperationException("Currency code unknown.");
    } 
 
    if (_currencyRepository.Exists(currencyCode))
    {
        CurrencyCode = currencyCode;
        Amount = amount;
        _currency = _currencyRepository.Get(CurrencyCode);
    }
    else
    {
        throw new InvalidOperationException("Currency code unknown.");
    }
} 
 
// Initialize a new money with the currency code of the 
// runtime enviroment's current regional settings.
public Money(decimal amount)
{
    CurrencyCodeKind currencyCode;
    try
    {
        currencyCode = (CurrencyCodeKind)Enum.Parse(typeof(CurrencyCodeKind), RegionInfo.CurrentRegion.ISOCurrencySymbol);
    }
    catch (Exception)
    {
        throw new InvalidOperationException("Currency code unknown.");
    } 
 
    if (_currencyRepository.Exists(currencyCode))
    {
        CurrencyCode = currencyCode;
        Amount = amount;
        _currency = _currencyRepository.Get(CurrencyCode);
    }
    else
    {
        throw new InvalidOperationException("Currency code unknown.");
    }
} 
 
As you can see, the constuctors use the _currencyRepository to find the currency object matching the current currency code. The currency repository is a singleton, being nothing more than a static in memory store of all possible currency objects. Here’s a snippet:
internal class CurrencyRepository
{
    // List of all currencies with their properties.
    static private Dictionary<CurrencyCodeKind, Currency> _currencyDictionary =
        new Dictionary<CurrencyCodeKind, Currency>()
        {
            {CurrencyCodeKind.AED, new Currency(CurrencyCodeKind.AED, "United Arab Emirates dirham", "¤", 2)},
            {CurrencyCodeKind.AFN, new Currency(CurrencyCodeKind.AFN, "Afghani", "¤", 2)},
            {CurrencyCodeKind.ALL, new Currency(CurrencyCodeKind.ALL, "Lek", "¤", 2)},
            {CurrencyCodeKind.AMD, new Currency(CurrencyCodeKind.AMD, "Armenian dram", "¤", 2)},
            {CurrencyCodeKind.ANG, new Currency(CurrencyCodeKind.ANG, "Netherlands Antillean guilder", "ƒ", 2)},
            ... 
The reasons all currency objects are hard coded are:
  1. the currency list hardly ever changes;
  2. when a new currency is introduced, it needs to be added to the CurrencyCodeKind enumeration anyway, thus requiring a new system build; it is only natural to then also update the hard coded currency object list;
  3. you don’t really want this core configuration of the way you handle money to be stored in an easy to corrupt/misuse configuration file.

One additional thing to note is that I quickly found out that the default character set does not hold all currency symbols. Therefore a lot of currency symbols are represented by the generic currency sign. A future enhancement will be to add the Unicode of the symbol to the properties of the Currency class.

Operators

The implementation of most arithmetic operators are straightforward; here’s the >, >=, ==, <=, <, !=, +, and - operators:

public static bool operator >(Money first, Money second)
{
    AssertSameCurrency(first, second);
    return first.Amount > second.Amount;
}
 
public static bool operator >=(Money first, Money second)
{
    AssertSameCurrency(first, second);
    return first.Amount >= second.Amount;
}
 
public static bool operator <=(Money first, Money second)
{
    AssertSameCurrency(first, second);
    return first.Amount <= second.Amount;
}
 
public static bool operator <(Money first, Money second)
{
    AssertSameCurrency(first, second);
    return first.Amount < second.Amount;
}
 
public static Money operator +(Money first, Money second)
{
    AssertSameCurrency(first, second);
    return new Money(first.CurrencyCode, first.Amount + second.Amount);
}
 
public static Money operator -(Money first, Money second)
{
    AssertSameCurrency(first, second);
    return new Money(first.CurrencyCode, first.Amount - second.Amount);
}
 
public static bool operator ==(Money first, Money second)
{
    if (object.ReferenceEquals(first, second)) return true;
    if (object.ReferenceEquals(first, null) || object.ReferenceEquals(second, null)) return false;
    return (first.CurrencyCode == second.CurrencyCode && first.Amount == second.Amount);
}
 
public static bool operator !=(Money first, Money second)
{
    return !first.Equals(second);
}
Where it starts getting tricky is with multiplication and division. This is because of the rounding that needs to take place when the result of the operation exceeds the number of significant decimal digits allowed for that currency. To tackle this, I’ve implemented the WithRoundedAmount() operation for both the * and / operators.
public static Money operator *(Money money, decimal value)
{
    if (money == null) throw new ArgumentNullException("money");
    return new Money(money.CurrencyCode, money.Amount * value).WithRoundedAmount();
}
 
public static Money operator /(Money money, decimal value)
{
    if (money == null) throw new ArgumentNullException("money");
    return new Money(money.CurrencyCode, money.Amount / value).WithRoundedAmount();
}


internal Money WithRoundedAmount()
{
    switch (_currency.RoundingType)
    {
        case CurrencyRoundingKind.Argentinian:
            decimal insignificantDecimals1 = Amount * CentFactor() - (long)Math.Truncate(Amount * CentFactor());
            if (insignificantDecimals1 < 0.3m)
            {
                return this.WithTruncatedAmount();
            }
            else
            {
                if (insignificantDecimals1 > 0.7m)
                {
                    Amount = decimal.Round(Amount, _currency.SignificantDecimalDigits, MidpointRounding.AwayFromZero);
                    return this;
                }
                else
                {
                    Amount = ((long)Math.Truncate(Amount * CentFactor()) + 0.5m) / CentFactor();
                    return this;
                }
            }
        case CurrencyRoundingKind.Swiss:
            decimal insignificantDecimals2 = Amount * CentFactor() - (long)Math.Truncate(Amount * CentFactor());
            if (insignificantDecimals2 < 0.26m)
            {
                return this.WithTruncatedAmount();
            }
            else
            {
                if (insignificantDecimals2 > 0.75m)
                {
                    Amount = decimal.Round(Amount, _currency.SignificantDecimalDigits, MidpointRounding.AwayFromZero);
                    return this;
                }
                else
                {
                    Amount = ((long)Math.Truncate(Amount * CentFactor()) + 0.5m) / CentFactor();
                    return this;
                }
            }
        default:
            Amount = decimal.Round(Amount, _currency.SignificantDecimalDigits, MidpointRounding.AwayFromZero);
            return this;
    }
}
As you can see, the WithRoundedAmount() is not as straightforward as expected, as is described in this source. The default (and much expected) behaviour for rounding is:
  • If the last digit is less than 5, drop it, otherwise,
  • If the last digit is equal to or above 5, add one to the previous digit and drop the last digit.
Apparently, Argentina and Switzerland have alternate rounding schemes, as described in the above mentioned source. To accommodate for these, I have added a CurrencyRoundingKind enumeration to indicate when to use what rounding scheme.
internal enum CurrencyRoundingKind
{
    AwayFromZero,
    Swiss,
    Argentinian
}
For now, I’ve associated that scheme to the Argentinian and Swiss currencies, but I’m not sure if that’s entirely correct. In other words: do Argentina and Switzerland only apply these rounding schemes to their own currencies, or also to all foreign currencies they perform calculations on? For now, I choose to leave this alone, since I currently don’t need to accommodate for this in my projects. But if someone can enlighten me… by all means!

Allocation

With rounding comes loss of information. If you use the division operator to calculate how to divide $0.05 amongst 3 people, you’ll have $0.01 to give to each person. $0.02 is lost due to rounding. Everyone knows about those exploit stories of programmers in the early days who took advantage of this loss due to rounding. We’ve wizened up since then, and Fowler introduced an Allocate algorithm to take care of situations like this. It’s a simple algorithm that actually plays the “rings on a sticks” game:

Say you have 5 rings and 3 sticks to divide them eenly over, you’ll get the following:

MoneyAllocate

With the Allocate algorithm, you’ll ask to Allocate $0.05 over 3 parts: (new Money(CurrencyCodeKind.USD, 0.05m)).Allocate(3). The result is an array with 3 elements, two of which contain $0.02 and one that contains $0.01.
public Money[] Allocate(int n)
{
    Money lowResult = new Money(CurrencyCode, Amount / n).WithTruncatedAmount();
    Money highResult = lowResult.Amount + new Money(this.CurrencyCode, 1.0m/CentFactor());
    Money[] results = new Money[n];
 
    int remainder = (int)((Amount * CentFactor()) % n);
    for (int i = 0; i < remainder; i++) results[i] = highResult;
    for (int i = remainder; i < n; i++) results[i] = lowResult;
 
    return results;
}
I’ve also included Fowler’s enhanced version of the Allocate algorithm, which allows to user to specify an array of allocation ratios, e.g. allocating $1 with a ratio of {2, 3, 3}, can result in an array with $0.25, $0.37 and $0.38. Note that I said can, because the algorithm does not assert how the division takes place exactly. It only asserts that:
  1. the remainder is evenly distributed over the parts
  2. the sum of the resulting amounts is equal to the divided amount.
public Money[] Allocate(int[] ratios)
{
    decimal total = 0m;
    for (int i = 0; i < ratios.Length; i++) total += ratios[i];
 
    Money remainder = this.Copy();
    Money[] results = new Money[ratios.Length];
    
    // First distribute the truncated amounts over all parts
    for (int i = 0; i < results.Length; i++) {
        results[i] = new Money(CurrencyCode, (this.Amount * ratios[i]) / total).WithTruncatedAmount();
        remainder.Subtract(results[i]);
    }
 
    
    // Now determine how many cents are left
    long centsLeftToDivide = (long)(remainder.Amount / (1.0m / CentFactor()));
 
    // Distribute those remaining cents over the different parts
    for (int i = 0; i < centsLeftToDivide; i++) {
        results[i].Add(new Money(this.CurrencyCode, 1.0m / CentFactor()));
    }
 
    return results;
}
So in order to apply “rounding safe divisions”, be sure to use the Allocate operation.

Formatting for displaying

Lastly, we'll need some formatting on a Money object for it to present itself neatly to a user. This formatting is included in the 3 variants of the ToString() operation:

  1. with no parameters (generally not recommended); the number formatting rules are taken from the OS' current culture info and the three letter currency code is used as the currency indicator;
  2. with a CultureInfo object as parameter (recommended); the number formatting rules are derived from the passed in CultureInfo object and the three letter currency code is used as the currency indicator;
  3. with a CultureInfo object as parameter and an indicator whether or not to use the currency symbol instead of the three letter currency code as currency indicator (equally recommended); the number formatting rules are derived from the passed in CultureInfo object.
public string ToString()
{
    return Amount.ToString("C", GetCurrencyFormatter(CultureInfo.CurrentCulture, false));
}
 
public string ToString(CultureInfo cultureInfo)
{
    return Amount.ToString("C", GetCurrencyFormatter(cultureInfo, false));
}
 
public string ToString(CultureInfo cultureInfo, bool useSymbol)
{
    return Amount.ToString("C", GetCurrencyFormatter(cultureInfo, useSymbol));
}

A central role is played by the GetCurrencyFormatter operation, which returns a NumberFormatInfo object that contains the desired currency indicator as well as an adapter currency formatting pattern that always makes sure there is a space between the currency indicator and the amount, if the currency indicator is a three letter currency code.

private NumberFormatInfo GetCurrencyFormatter(CultureInfo cultureInfo, bool useSymbol)
{
    // Get all the basics from the passed in culture info (not before it is 
    // guaranteed to use global settings)
    NumberFormatInfo LocalNumberFormatter = (NumberFormatInfo)this.GetGlobalCultureInfo(cultureInfo).NumberFormat.Clone();
 
    // Overwrite the culture settings with the specifics of the current currency
    Currency currency = _currencyRepository.Get(CurrencyCode);
    LocalNumberFormatter.CurrencyDecimalDigits = currency.SignificantDecimalDigits;
    if (useSymbol)
    {
        LocalNumberFormatter.CurrencySymbol = currency.Symbol;
    }
    else
    {
        LocalNumberFormatter.CurrencySymbol = Enum.GetName(typeof(CurrencyCodeKind), CurrencyCode);
 
        // If we use the ISO code, then we need to make sure the patterns always include 
        // a space between the ISO code and the amount.
        if (LocalNumberFormatter.CurrencyPositivePattern <= 1)
        {
            LocalNumberFormatter.CurrencyPositivePattern = LocalNumberFormatter.CurrencyPositivePattern + 2;
        }
 
        switch (LocalNumberFormatter.CurrencyNegativePattern)
        {
            case 0: // ($n)
                LocalNumberFormatter.CurrencyNegativePattern = 14;
                break;
            case 1: // -$n
                LocalNumberFormatter.CurrencyNegativePattern = 9;
                break;
            case 2: // $-n
                LocalNumberFormatter.CurrencyNegativePattern = 12;
                break;
            case 3: // $n-
                LocalNumberFormatter.CurrencyNegativePattern = 11;
                break;
            case 4: // (n$)
                LocalNumberFormatter.CurrencyNegativePattern = 15;
                break;
            case 5: // -n$
                LocalNumberFormatter.CurrencyNegativePattern = 8;
                break;
            case 6: // n-$
                LocalNumberFormatter.CurrencyNegativePattern = 13;
                break;
            case 7: // n$-
                LocalNumberFormatter.CurrencyNegativePattern = 10;
                break;
            default:
                break;
        }
    }
    return LocalNumberFormatter;
}
 
private CultureInfo GetGlobalCultureInfo(CultureInfo cultureInfo)
{
    if (!cultureInfo.UseUserOverride)
    {
        //The passed in culture info is already in "global mode" 
        return cultureInfo;
    }
    else
    {
        // The passed in culture info is set to use OS specific 
        // culture settings; this should be changed.
        return new CultureInfo(cultureInfo.Name, false);
    }
}

Wrapping it up

Jee wizz... that's a lot of explainin', Batman! Yeah, well... there's still a bit more in the actual code that I have not covered in detail, but this story should have you covered for regular use. If -after this whole epistle- you're still interested in the actual code, you can get your copy here:

Download the C# Money implementation

Oh yeah... do note that this all is built in Visual Studio 2008 Professional, so you might run into some problems if you try to use it directly in an older version of Visual Studio. Sorry for that!

Gimme feedback!

This is only my first go at a decent Money implementation. The unit test set can use some extension and cleaning up; I'm aware of that. Furthermore, the implementation will certainly get updated based on requirements within projects I use it in. But also, I hope to get feedback from you with suggestions, new insights, updates of rules (e.g. the rounding schemes), updates of code, etc. Especially I’d like feedback from foreign readers who find that this implementation needs adaptation to work correctly in their country, with their currency. Use this implementation freely and let me know it can be improved!

Thursday, June 21, 2007

Stop comparing software development with mass production!

I started reading Real-Life MDA: Solving Business Problems with Model Driven Architecture the other night. The introduction goes into a detailed description of how it took many decades to get mass production of goods going. It suggests that it is logical that it takes some time for software development to reach that mass production stage as well.

Obviously, this is not the first book or article to suggest that it is strange that we have mass production of goods, but in software engineering we’re still up to the level of a specialized craft-based shops that manufacture unique products every time. However, I think the comparison between software development and mass production is completely inappropriate, since both concepts are on a different meta-level.

An example

Let’s look the automotive industry, for example. The book suggests that software development should reach the same “mass production line” stage as the production line in which cars are produced. But what is that car manufacturing production line exactly? It’s actually a mass replication of one super-prototype model in which years of design, development and test work have been put. Creating that super-prototype is a real craft and has involves no production line manufacturing whatsoever.

Now, to draw the correct parallel: software development is actually all about creating that super-prototype. The whole mass replication is a step that is almost always conveniently overlooked in the software development, since it’s so trivial: at best it's equivalent to producing the media (cd’s, dvd’s) on which the software is distributed, or providing the webspace links and bandwith to download the software from. In software, this is so trivial, I’m almost tempted to conclude that software development is way ahead of the regular mass production industry!

Then what are the correct parallels?

Now that I’m at it, I like to complete the comparison on the correct meta-level. I’ll do that with the example of the automotive industry again.

Build to order

First of all, the automotive industry is known for its flexible mass production: the customer chooses a certain car model and then selects number of configuration options. The parallel with software development is that the customer chooses a COTS product, e.g. SAP/R3, and has somebody over to install and tailor the product for that particular customer’s organisation.

Product lines

In the last two decades the automotive industry has invested heavily in reducing the time and costs for creating super-prototypes. Take Volkswagen, for example: the latest models of the Golf, Passat, Jetta, etc. have more commonalities than ever! Volkswagen has invested in setting up a product line in which all models share as many components as possible. That reduces development and testing costs, as well as maintenance costs. This is the same shift that has been initiated in software development: creating software product lines (also see Software Factories: Assembling Applications with Patterns, Models, Frameworks, and Tools).

Conclusion

In short: I think that the difference in maturity between software development and mass production is far smaller than often suggested. Even in a (generally perceived) mature industry as the automotive industry, the development of new production-ready super-prototypes is still a huge undertaking. It is unlikely that this will become a highly automated process anytime soon, since it involves a lot of creative work. So in software development, the industrialization that can be expected is most likely of the same magnitude as the ongoing industrialization of the established mass production lines.

Thursday, May 24, 2007

Agile DDD (with TDD and in memory repositories)

Agile DDD

I love the core concept of Domain Driven Design: separate business logic from technical logic and focus your efforts on the first, since that's what's supposed to earn you money. Like all brilliant ideas: simple but highly effective.

So you set out on a Domain Driven Design & Development project, in which the incremental discovery of the domain plays central role. Start off with your first design, talk through it with domain experts, find out that it needs adjustment, etc, etc. To keep the discovery cycle as efficient as possible, we need an agile approach, building quick prototypes and finding out how they works for us. Early and frequent (unit)testing helps tremendously.

Repositories

All this is great, but how does this work in practice? The domain model sits completely isolated, ready to have a very agile go on with testing. But before we can do so, the domain model needs to be instantiated with data. This is where we use repositories to load stuff from a data storage (usually a relational database) an create domain objects with that data. The way back works exactly the same: saving domain objects is nothing more than a friendly request to the repository to save a domain model to the data storage.

As you can imagine, a lot of technical nitty gritty goes on in the repository, and as we said earlier: we don't want too much technical stuff on our heads to distract us from the business stuff. Luckily, a lot of repository-like functionality can be realized with an object relational mapper. In the .NET domain, I really like NHibernate. NHibernate simplifies the mapping of the domain to the relational database greatly, but still: try changing a domain class and you'll have to change the database, change a NHibernate mapping file and (possibly) migrate your test data that's already in your database. This is all still simple when you just change an attribute, but when relationships between classes start to change, stuff gets a whole lot more complex. I find that this significantly slows me down in my agile DDD process.

In memory repositories

But why do we need to go to the database anyway? For prototyping, we just want to load up instances we can play around with, save them, load them again later, etc. Furthermore, in this stage of the process we don't need to worry about enabling multiple users to use the system, etc. So why not simply use a repository for prototyping purposes, which keeps all domain instances in memory. It saves us huge amounts of time if we don't need to keep a relational representation of the domain model, as well as the mappings to that representation, in sync with our domain model. Secondly, the in memory repositories make unit testing a breeze, since we can very easily create test sets in memory and work on them very efficiently, without ever having the hassle of going through the whole object relational mapping.

Switching between repositories

Of course, the mapping to real storage needs to be done at some point in the process, and I found that Dave Donaldson's NHibernateRepository is a really good start. So, in the real system, we would like to substitute our in memory repository with a real one, like NHibernateRepository. To make this transition a piece of cake, we'd best adhere to the same interface. So I created a generic IRepository interface that should be matched by both the in memory repository and the NHibernate repository. There we immediately run into a drawback of the current implementation of NHibernateRepository: it has a good number of static methods, which we cannot define in the IRepository. Since I value having a uniform interface more than being able to load instances from a repository without having to instantiate it, I have decided to turn the static methods into instance methods.

So far so good: we now have an IRepository, which everyone can use to load and save stuff from and to. But how do we instantiate the correct repository instance? Dependency injection is the keyword here. I like using the Windsor container, which is part of the great Castle framework. BTW, Oren Eini's article on these topics is really worth a read. Anyway, in short: in the test phase we have Windsor injecting the in memory repository into the system as IRepository implementation and in the production phase we have Windsor injecting our variant of the NHibernateRepository.

Code please!

Yes... here we go. Firstly, do keep in mind that this is work in progress and that this is a first draft. I took the aforementioned NHibernateRepository and commented out everything I didn't need to get started with an in memory repository and placed the method signatures in the IRepository. For this IRepository, I created the InMemoryRepository. Feel free to use them as you please. I will continue to refine the for my own benefits and I'll be sure to post newer versions of them here on my blog. Note that I have not included the adapted HNibernateRepository, since adapting this is (at this point in time) still straight forward.

Here's where you find all the code.

Further considerations

One of the things I don't like about Dave's NHibernateRepository (apart from the static methods), is that is has a number of methods that allow the use of HQL, which is NHibernate specific. I'd like to keep the IRepository free of any technology specific stuff. Instead, a more generic approach to specifying selection criteria would be very welcome. Tim McCarthy has already put some work into implementing the Specification pattern, drawn up by Eric Evans and Martin Fowler, which is a good start. Still, I think there is more to gain here and that's what my next blog will be about.

Tuesday, November 07, 2006

Practical MDA with Acceleo

MDA
I gained interest in MDA in much the same way as I gained interest in digital photography: for a long time I did not really consider using it in my day to day practice, since the technology was too immature to be used seriously in real life. It was only in June 2006 that Ron Kersic (author of the Enterprise MDA Workbench), Bob Groeneveld and I sat down and had a look at what the Enterprise MDA Workbench was capable of at that time. That looked very promising and that's when I decided to get down 'n dirty. The Workench had a lot of potential, but when Ron found out about Acceleo and pointed it out to us, it was clear that it was miles ahead of any MDA tool that was (and still is) out there. Only a few months before, the French company Obeo contributed her Acceleo MDA tool to the Open Source community. And what an addition it is! Here's a quick glance at what I liked about it.

Acceleo
First of all, Acceleo is Eclipse based and uses the full potential of the Eclipse Modeling Framework (EMF). One benefit of EMF is that any modeling language that can be expressed in it and can be used as a basis to transform from. The most obvious language is UML and that's what I used it with. All model elements can be browsed with the Acceleo Reflective Editor.

Selecting a model element allows you to view all its meta-model properties and values. That, for starters, is a very powerful way to find your way around the modeling language's metamodel ("where is that association role name stored again?").

Templates
Acceleo is template based. That means that you'll create a template for each artifact you want to generate. You choose the model element you base your template on, which is the root of the navigation path through the instance of the metamodel. In the example below the "<%script type="core.Class"..." indicates that the tamplate is based on the "Class" model element and that all references to other model elements are relative to "Class". The most common things to be generated from a class is a Java or .NET class, data access objects, etc.


Another common metamodel element to generate from the the model as a whole ("Core.Model"). One can, for example, generate a database creation script, configuration files, etc.

The template is a mix of static text and macro-style commands which are used to extract data from the metamodel into the actual template. The beauty of Acceleo's Refective Editor is that the template can immediately be tested by applying it to one of the model elements in the model element browser.


This "preview functionality" displays a window that shows the static text in purple and the dynamic text (resulting from the macro statements) in black.

Services
Next to the templates, you can also create your own Java classes with functionality that can be accessed from the templates. This allows you full control over your metamodel, without making your templates overly complex.

Rock solid
A hidden gem is the great exception handling of the tool. I made some pretty weird mistakes in my templates, but still Acceleo remains stable and produces comprehensive error messages in both template previews and templates themselves, based on which errors can quickly be corrected.

Java? .NET?
The reader who has been paying close attention, might have noticed that my examples are build around generated C# classes. Indeed, most of our current projects are in .NET and so I concentrated primarely on generating .NET. That's no problem whatsoever, although we do miss out on some great features that Acceleo Pro (read on) has to offer the Java community.

And the results are?
In a bit of spare time, I managed to create Acceleo templates for the following artifacts (for our .NET environment):

  • domain classes (entity, value, enumeration)
  • repository & factory interfaces and implementations
  • NHibernate mapping files
  • database creation script (DDL)
  • miscelanious Visual Studio solution, project and configuration files
  • simple UI code to easily adapt for testing

This allowed us to get a very good head start on our project by immediately generating our domain model into our reference architecture. This was especiay valuable to the new developers that were not familiar with the reference architecture yet.

Availibility
As mentioned, Acceleo is Open Source, thus freely downloadable and usable for everyone. That's brilliant. There is a downside, though: only a subset of documentation and a handful of examples are available for free. The extensive user and reference manuals are for sale.

Acceleo Pro
Next to the Open Source Acceleo, Obeo offers Acceleo Pro. I was lucky enough to witness a very cool demo of this product. Now this is where I started wishing I was delivering Java projects instead of .NET. By far the coolest feature of Acceleo Pro is Acceleo Pro Tracibility. It is Obeo's solution to those round trip engineering desires that pop up once you're getting the hang of the ease of forward engineering. What it does is that it keeps track of what a developer does with the generated code. Acceleo already offers the ability to define "user code" blocks that will not be overwritten when regenerating code. But that does not prevent a developer to change generated code outside of these blocks. Acceleo Pro Tracibility uses the features of Eclipse cleverly to track these "illegal changes" and flag them. The developer can then choose what to do with the flag: mark the change as "user code", automatically update the template, etc. It's the most practical solution to keeping code and model in sync I've seen so far and it shows the power of having an all Eclipse based modeling and development environment. Unfortunately, this is where the .NET developers will have to stand by and watch the Java guys have a ball!

Conclusion
Rereading this post myself, I must say that it almost seems that I'm some kind of an Obeo spokesperson, but let me assure you: I'm not! I'm just genuinely excited about this very powerful, yet practical way of practicing MDA. If you are as sceptical about MDA as I was, but you definitely see potential, then I highly recommend you give Acceleo a try. It's free! Even if the full set of documentation is not freely available, I feel you can get very far with just the documentation and examples supplied on Obeo's website. And in the end there's still the Acceleo forum, which is closely monitored by very helpful Acceleo development team members.

Thursday, October 19, 2006

Use cases and CRUD functionality

Oh yes! Don't you just love use cases? They raise so many questions especially for the rather novice information analysts (but even the advanced once have their struggles now and then). And who hasn't struggled with questions about the right level of abstraction? A classic example is the description of CRUD functionality in use cases. Only just now I ran into this great post by Jim (Shaw?) on the Enterprise Architect forum, in which he expresses his view on this subject. If you're still wondering how to handle CRUD in and around use cases, take some of his advice: http://www.sparxsystems.com.au/cgi-bin/yabb/YaBB.pl?board=UMLPRO;action=display;num=1148378462;start=10#10 .