3

This link describes a function on a Money object for adding funds together of different currencies.

First I do not want to use the Service Locator pattern. I currently use a pattern of not having the Money object do the conversion itself. It just throws if you try and add different currencies together.

I have the object which owns Money objects (i.e. MultiCurrencyAccount) handle the math operations on Money. My problem is that I am currently constructor injecting a IMoneyConverter into the MultiCurrencyAccount domain object. This feels dirty to me since the IMoneyConverter is really a service which in turn uses a IForeignExchangeService (this one can hit the DB). I know I am not supposed to care about the implementation, since I am dealing with an abstraction, but it feels weird.

I am not sure if I am off base and injecting a service into my domain object is "correct" or if there is a more elegant way to do this.

Paul Hiemstra
  • 59,984
  • 12
  • 142
  • 149
phil
  • 618
  • 2
  • 5
  • 17
  • To get this straight: You want to add money of different currencies (e.g. USD and EUR). You have a service that does that (MultiCurrencyAccount) which uses an `IMoneyConverter` to convert the different currencies into the target currency. The implementation of the `IMoneyConverter` uses an `IForeignExchangeService` to lookup the exchange rates for the conversion. Sounds reasonable although I'm not sure if you really need the converter when your `IForeignExchangeService` already does the conversion. – Sebastian Weber Feb 04 '12 at 07:43
  • Sebastian you pretty much have it right. The reason for the IForeignExchangeService is that is just provides the rates and the IMoneyConverter actually has the conversion math in it. – phil Feb 04 '12 at 22:42

1 Answers1

3

If you treat Money as Value Objects (which makes tons of sense), it's very tempting to design them with built-in conversion functionality.

However, since you refer to a link about Domain-Driven Design, you should ask yourself if that's actually the correct way to model Money?

In most cases, a bundle of US Dollars aren't just magically going to turn themselves into their equivalent value in Euros. You'd have to take them to some exchange station to trade your Dollars into Euros. Once you've done that, now you have Euros, and no Dollars. If the exchange rate changes afterwards, it's not going to affect the amount of Euros you now have.

I'm not saying that it's always going to be like that. In the end, it depends on your business domain, but I'd think it highly likely that if you ask your business experts you'll find that the business rules for currency trading are decoupled from the money itself. If this is the case, it makes more sense to model currency exchange as a Service separate from the Value Object.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
  • Thank you Mark. I have designed our Money object as an immutable value object and I really do like that pattern. Do you have an opinion if injecting the IMoneyConverter into a domain object is smelly? What really brought this up for me was that my Repository must inject a IMoneyConverter into the domain object before passing it to the service layer for use. – phil Feb 05 '12 at 16:46
  • I think it's smelly, but not clear-cut: http://stackoverflow.com/questions/4835046/why-not-use-an-ioc-container-to-resolve-dependencies-for-entities-business-objec/4836790#4836790 – Mark Seemann Feb 05 '12 at 17:43