Skip to content

Instantly share code, notes, and snippets.

@serialseb
Created May 16, 2014 12:40
Show Gist options
  • Save serialseb/f2387fd65a02391a72de to your computer and use it in GitHub Desktop.
Save serialseb/f2387fd65a02391a72de to your computer and use it in GitHub Desktop.
A more compositional approach
public class Wireup
{
public void DoWireup()
{
var identity = new IdentityFormatter();
var stringFormat = new FormattingStringFormatter();
// that would normally get registered in your container or what not.
Selectors = new[]
{
new AggregateFormatter(IsDouble, Converters.Double, identity, stringFormat),
new AggregateFormatter(IsSingleSelectList, Converters.SelectListLong, identity,stringFormat,new SelectOptionFormatter()),
new AggregateFormatter(IsPerson, identity,stringFormat, new PersonNameFormatter(null)),
new AggregateFormatter(_=>true, identity,stringFormat)
};
}
static bool IsPerson(IField arg)
{
return arg.Type == FieldType.Person;
}
static bool IsSingleSelectList(IField arg)
{
return arg.Type == FieldType.Selection &&
(arg.SelectListType == SelectListType.Radio || arg.SelectListType == SelectListType.Select) &&
arg.SelectListSubType.HasValue;
}
static bool IsDouble(IField arg)
{
return arg.Type == FieldType.Number || arg.Type == FieldType.Range || arg.Type == FieldType.Money;
}
public IEnumerable<IFieldSelector> Selectors { get; set; }
}
public enum SelectListType
{
Radio,
Select
}
public interface IFieldSelector : IFieldFormatter
{
bool CanFormat(IField field);
}
public interface IFieldFormatter
{
IEnumerable<Tuple<string, object>> GetEntries(IField field, object value);
}
public class ChangeApplier
{
readonly IEnumerable<IFieldSelector> formatters;
public ChangeApplier(IEnumerable<IFieldSelector> formatters)
{
this.formatters = formatters;
}
public void ApplyChange(IField field, object newValue, Record record, bool overwrite)
{
var formatter = GetFormatterFor(field);
foreach (var change in formatter.GetEntries(field, newValue))
record.AddOrSetValue(change.Item1, change.Item2, overwrite);
}
IFieldFormatter GetFormatterFor(IField field)
{
return formatters.FirstOrDefault(_ => _.CanFormat(field));
}
}
public static class Converters
{
public static object Double(IField field, object fieldValue)
{
if (fieldValue == null) return null;
if (field.SelectListSubType != SelectListSubType.Numeric) return fieldValue;
double value = 0D;
double.TryParse(fieldValue.ToString(), out value);
return value;
}
public static object SelectListLong(IField field, object fieldValue)
{
if (fieldValue == null) return 0;
if (fieldValue is long) return fieldValue;
long val = 0;
long.TryParse(fieldValue.ToString(), out val);
return val;
}
}
public class AggregateFormatter : IFieldFormatter, IFieldSelector
{
readonly Func<IField, bool> selector;
readonly Func<IField, object, object> valueConverter;
readonly IFieldFormatter[] formatters;
public AggregateFormatter(Func<IField, bool> selector, params IFieldFormatter[] formatters)
: this(selector, _ => _, formatters)
{
}
public AggregateFormatter(Func<IField, bool> selector, Func<IField, object, object> valueConverter, params IFieldFormatter[] formatters)
{
this.selector = selector;
this.valueConverter = valueConverter;
this.formatters = formatters;
}
public IEnumerable<Tuple<string, object>> GetEntries(IField field, object value)
{
value = valueConverter(field, value);
return formatters.SelectMany(_ => _.GetEntries(field, value));
}
public bool CanFormat(IField field)
{
return selector(field);
}
}
public class IdentityFormatter : IFieldFormatter
{
public IEnumerable<Tuple<string, object>> GetEntries(IField field, object value)
{
yield return Tuple.Create(field.Identifier, value);
}
}
public class FormattingStringFormatter : IFieldFormatter
{
string formatSuffix;
public IEnumerable<Tuple<string, object>> GetEntries(IField field, object value)
{
if (field.FormatString != null)
yield return Tuple.Create(field.Identifier + formatSuffix, (object)string.Format(field.FormatString, value));
}
}
public class SelectOptionFormatter : IFieldFormatter
{
public IEnumerable<Tuple<string, object>> GetEntries(IField field, object value)
{
yield return Tuple.Create(field.Identifier + ".SELECTText", (object)field.SelectListOptions.TextFor(value));
}
}
public class PersonNameFormatter : IFieldFormatter
{
Func<object, object> personNameProvider;
public PersonNameFormatter(Func<object, object> personNameProvider)
{
this.personNameProvider = personNameProvider;
}
public IEnumerable<Tuple<string, object>> GetEntries(IField field, object value)
{
yield return Tuple.Create(field.Identifier + ".THATGUY", this.personNameProvider(value));
}
}
public static class UsefulExtensions
{
public static string TextFor(this IEnumerable<SelectOption> options, object value)
{
return options.FirstOrDefault(o => o.Value == (value ?? string.Empty).ToString()).Text;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment