When I first hacked together Suteki Shop, I used the decimal type everywhere I needed to represent money. This has mostly worked well for the simple scenario where a shop only has a single currency and that currency is sterling (£). But anyone wanting to sell in US dollars had to find every one of the many instances of “£” and replace them with “$”, and if you wanted to do something fancy with multiple currencies, you would have been out of luck. What I needed was a Money type. It’s not a trivial refactoring. Here are the steps I needed to take:
Create a Money type that behaved as far as possible like a .NET numeric type.
Create an ASP.NET MVC IModelBinder that knew how to bind the Money type.
Create an NHibernate IUserType that knew how to persist the Money type.
Change every point in the code that was using decimal to represent money to use the Money type instead.
Create a Money type
I wanted to create a Money type that would behave nicely when I did arithmetic with it. So I wanted to be able to write expression like this:
var x = new Money(43.5M);
var result = x * 3 + x/2 - 4;
result.Amount.ShouldEqual(148.25M);
To achieve this you have to write a lot of operator overloads for all combinations of operator, Money <-> Money, Money <-> decimal and decimal <-> Money. I won’t bore you, if you want to see the gory details, you can view the code here.
Read more: CODE RANT