Created
May 16, 2014 12:40
-
-
Save serialseb/f2387fd65a02391a72de to your computer and use it in GitHub Desktop.
A more compositional approach
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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