Created
October 2, 2017 21:43
-
-
Save omerfarukz/9b149df718c59e452288e880f2d6de29 to your computer and use it in GitHub Desktop.
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
namespace Mapping | |
{ | |
public class Mapper | |
{ | |
private Configuration _configuration; | |
public Mapper(Configuration configuration) | |
{ | |
_configuration = configuration; | |
} | |
public TTarget Map<TSource, TTarget>(TSource source) | |
{ | |
var function = _configuration.GetMapFunction<TSource, TTarget>(); | |
if (function == null) | |
throw new InvalidProgramException(); | |
return (TTarget)function(source); | |
} | |
} | |
public interface IMappingDefinition | |
{ | |
Type Source { get; set; } | |
Type Target { get; set; } | |
Func<object, object> Map { get; set; } | |
} | |
public class MappingDefinition : IMappingDefinition | |
{ | |
public Type Source { get; set; } | |
public Type Target { get; set; } | |
public Func<object, object> Map { get; set; } | |
} | |
public class MappingDefinition<TSource, TTarget> : MappingDefinition | |
{ | |
public MappingDefinition(Func<TSource, TTarget> map) | |
{ | |
Source = typeof(TSource); | |
Target = typeof(TTarget); | |
Map = (f) => map((TSource)f); | |
} | |
} | |
public class Configuration | |
{ | |
private Dictionary<Type, IDictionary<Type, IMappingDefinition>> _mappingDefinitions; | |
public Configuration() | |
{ | |
_mappingDefinitions = new Dictionary<Type, IDictionary<Type, IMappingDefinition>>(); | |
} | |
public Configuration Add<TSource, TTarget>(Func<TSource, TTarget> map) | |
{ | |
var mappingDefinition = new MappingDefinition<TSource, TTarget>(map); | |
return Add(mappingDefinition); | |
} | |
public Configuration Add(IMappingDefinition mappingDefinition) | |
{ | |
if (!_mappingDefinitions.ContainsKey(mappingDefinition.Source)) | |
_mappingDefinitions.Add(mappingDefinition.Source, GetEmptyCollection()); | |
var entry = _mappingDefinitions[mappingDefinition.Source]; | |
if (entry.ContainsKey(mappingDefinition.Target)) | |
throw new InvalidProgramException(); | |
entry.Add(mappingDefinition.Target, mappingDefinition); | |
return this; | |
} | |
public Configuration Fit() | |
{ | |
foreach (var left in _mappingDefinitions) | |
{ | |
foreach (var right in left.Value) | |
{ | |
right. | |
} | |
} | |
return this; | |
} | |
public Func<object, object> GetMapFunction<TSource, TTarget>() | |
{ | |
var mappingDefinition = Get(typeof(TSource), typeof(TTarget)); | |
if (mappingDefinition == null) | |
throw new InvalidProgramException(); | |
return mappingDefinition.Map; | |
} | |
public IMappingDefinition Get<TSource, TTarget>() | |
{ | |
var mappingDefinition = Get(typeof(TSource), typeof(TTarget)); | |
return mappingDefinition; | |
} | |
public IMappingDefinition Get(Type source, Type target) | |
{ | |
if (!_mappingDefinitions.ContainsKey(source)) | |
throw new InvalidProgramException(); | |
var entry = _mappingDefinitions[source]; | |
if (!entry.ContainsKey(target)) | |
throw new InvalidProgramException(); | |
return entry[target]; | |
} | |
private IDictionary<Type, IMappingDefinition> GetEmptyCollection() | |
{ | |
return new Dictionary<Type, IMappingDefinition>(); | |
} | |
} | |
public static class ConfigurationExtensions | |
{ | |
public static Configuration AddDefaultTypes(this Configuration configuration) | |
{ | |
configuration.Add<Int32, Int64>((f) => f); | |
configuration.Add<Int16, Int32>((f) => f); | |
configuration.Add<byte, Int16>((f) => f); | |
configuration.Add<Int64, float>((f) => f); | |
configuration.Add<Int32, float>((f) => f); | |
configuration.Add<Int16, float>((f) => f); | |
configuration.Add<byte, float>((f) => f); | |
configuration.Add<Int64, double>((f) => f); | |
configuration.Add<Int32, double>((f) => f); | |
configuration.Add<Int16, double>((f) => f); | |
configuration.Add<byte, double>((f) => f); | |
configuration.Add<Int64, string>((f) => f.ToString()); | |
configuration.Add<Int32, string>((f) => f.ToString()); | |
configuration.Add<Int16, string>((f) => f.ToString()); | |
configuration.Add<byte, string>((f) => f.ToString()); | |
configuration.Add<sbyte, string>((f) => f.ToString()); | |
configuration.Add<float, string>((f) => f.ToString()); | |
configuration.Add<double, string>((f) => f.ToString()); | |
return configuration; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment