Skip to content

Instantly share code, notes, and snippets.

@omerfarukz
Created October 2, 2017 21:43
Show Gist options
  • Save omerfarukz/9b149df718c59e452288e880f2d6de29 to your computer and use it in GitHub Desktop.
Save omerfarukz/9b149df718c59e452288e880f2d6de29 to your computer and use it in GitHub Desktop.
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