Pierre Greborio.NET

Talking about .NET world

[Money Pattern] Formatting

Calling ToString method will shows the amount value without any currency symbol/name/ISO code. In order to show the correct money formatting we have two choices:

  1. Define a static formatting rule
  2. Create a custom formatter

Personally I prefer the second option so that the user (of the Money class) can decide which formatting to use in any context. Consider to build a custom formatter:

public class CurrencyFormatInfo : IFormatProvider, ICustomFormatter
{
 private const string FORMAT_NAME = "mn";
 private const string FORMAT_SYMBOL = "ms";
 private const string FORMAT_ISO = "mi";

 public object GetFormat(Type formatType)
 {
  if (formatType != typeof(ICustomFormatter))
   return null;
  else
   return this;
 }

 public string Format(string format, object arg, IFormatProvider formatProvider)
 {
  if (arg == null) throw new ArgumentNullException("arg");

  if((!string.IsNullOrEmpty(format)) && (arg is Money))
  {
   string s = format.Trim().ToLower();
   if (s.StartsWith("m"))
    return FormatMoney(arg as Money, format, formatProvider);
  }

  if (arg is IFormattable)
   return ((IFormattable)arg).ToString(format, formatProvider);
  else return arg.ToString();
 }

 private string FormatMoney(Money m, string format, IFormatProvider formatProvider)
 {
  switch (format)
  {
   case FORMAT_NAME:
    return string.Concat(m.Amount.ToString(formatProvider), " ", m.Currency.Name);
   case FORMAT_ISO:
    return string.Concat(m.Amount.ToString(formatProvider), " ", m.Currency.ISOCode);
   case FORMAT_SYMBOL:
    return string.Concat(m.Amount.ToString(formatProvider), " ", m.Currency.Symbol);
   default:
    return m.Amount.ToString(formatProvider);
  }
 }
}

In the above sample I defined three basic format strings, it is clear that in real-world situations you could decide to create more (and complex) choices. Once the format provider is defined we can then create all our ToString overrides:

public override string ToString()
{
 return (new CurrencyFormatInfo()).Format("m", this, null);
}

public string ToString(string format)
{
 return (new CurrencyFormatInfo()).Format(format, this, null);
}

public string ToString(string format, IFormatProvider formatProvider)
{
 if (string.IsNullOrEmpty(format))
  format = "m";

 return (new CurrencyFormatInfo()).Format(format, this, formatProvider);
}

Comments

No Comments