Skip to content

Instantly share code, notes, and snippets.

@svenschelfaut
Created March 21, 2014 11:08
Show Gist options
  • Save svenschelfaut/9683950 to your computer and use it in GitHub Desktop.
Save svenschelfaut/9683950 to your computer and use it in GitHub Desktop.
Using value objects with external services. Is this a good method?
using System;
namespace MoneyTest
{
public static class Program
{
static void Main(string[] args)
{
var twentyEuro = 20.0.Euro();
var twentyDollar = 20.0.Dollar();
var converter = new MoneyConverter(new ExchangeRateService());
var twentyDollarInEuro = converter.Convert(twentyDollar, Currency.EUR);
Console.WriteLine("20 USD in euro: " + twentyDollarInEuro);
var sum = twentyEuro + twentyDollarInEuro;
Console.WriteLine("Result 20 EUR + 20 USD: " + sum);
Console.ReadLine();
}
}
public enum Currency
{
USD,
EUR
}
public sealed class MoneyConverter
{
private readonly IDetermineExchangeRate _exchangeRateService;
public MoneyConverter(IDetermineExchangeRate exchangeRateService)
{
_exchangeRateService = exchangeRateService;
}
public Money Convert(Money money, Currency toCurrency)
{
var exchangeRate = _exchangeRateService.DetermineExchangeRate(money.Currency, toCurrency);
return new Money(exchangeRate * money.Amount, toCurrency);
}
}
public interface IDetermineExchangeRate
{
double DetermineExchangeRate(Currency fromCurrency, Currency toCurrency);
}
public class ExchangeRateService : IDetermineExchangeRate
{
public double DetermineExchangeRate(Currency fromCurrency, Currency toCurrency)
{
if (fromCurrency == toCurrency)
return 1;
if (fromCurrency == Currency.EUR && toCurrency == Currency.USD)
return 1.37;
if (fromCurrency == Currency.USD && toCurrency == Currency.EUR)
return 0.72;
throw new ArgumentException(string.Format("No exchange rate available for {0} to {1}", fromCurrency, toCurrency));
}
}
public sealed class Money
{
public double Amount { get; private set; }
public Currency Currency { get; private set; }
public Money(double amount, Currency currency)
{
Amount = amount;
Currency = currency;
}
public static Money operator +(Money money1, Money money2)
{
CheckThatCurrenciesAreTheSame(money1, money2);
return new Money(money1.Amount + money2.Amount, money1.Currency);
}
public static Money operator -(Money money1, Money money2)
{
CheckThatCurrenciesAreTheSame(money1, money2);
return new Money(money1.Amount - money2.Amount, money1.Currency);
}
private static void CheckThatCurrenciesAreTheSame(Money money1, Money money2)
{
if (money1.Currency != money2.Currency)
{
throw new ArgumentException(
string.Format("Can't add {0} to {1}", money2.Currency, money1.Currency));
}
}
private bool Equals(Money other)
{
return Amount.Equals(other.Amount) && Currency == other.Currency;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((Money)obj);
}
public override int GetHashCode()
{
unchecked
{
return (Amount.GetHashCode() * 397) ^ (int)Currency;
}
}
public override string ToString()
{
return string.Format("{0} {1}", Amount, Currency);
}
}
public static class MoneyExtensions
{
public static Money Euro(this double amount)
{
return new Money(amount, Currency.EUR);
}
public static Money Dollar(this double amount)
{
return new Money(amount, Currency.USD);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment