using System;
using System.Collections.Generic;
using System.Linq;
namespace Quadarax.Foundation.Core.Mapper
{
///
/// Lightweight Object-to-Object Mapper.
///
public class Loom
{
///
/// Defines a new mapping function using a configuration-driven builder.
///
/// The source type.
/// The destination type.
///
public LoomBuilder Define()
where TFrom : class
where TTo : class, new()
{
return new LoomBuilder(this);
}
///
/// Defines a new mapping function.
///
/// The source type.
/// The destination type.
/// The mapping function.
public void Define(Action map)
{
Dictionary inner;
if (!_maps.TryGetValue(typeof(TFrom), out inner))
{
inner = new Dictionary();
_maps[typeof(TFrom)] = inner;
}
inner[typeof(TTo)] = map;
}
///
/// Finds a mapping function.
///
/// The source type.
/// The destination type.
/// The mapping function for the given combination of types or a null reference when not defined.
public Action Find()
{
Dictionary inner;
if (!_maps.TryGetValue(typeof(TFrom), out inner)) return null;
Delegate map;
if (!inner.TryGetValue(typeof(TTo), out map)) return null;
return (Action) map;
}
///
/// Updates the destination object from the source using a mapping function.
///
/// The source type.
/// The destination type.
/// The source object.
/// The destination object.
public void Update(TFrom from, TTo to)
where TFrom : class
where TTo : class
{
if (from == null) throw new ArgumentNullException("from");
if (to == null) throw new ArgumentNullException("to");
Find()(from, to);
}
///
/// Creates a destination object from the source using a mapping function.
///
/// The source type.
/// The destination type.
/// The source object.
/// The destination object or a null reference in case is a null reference, too.
public TTo Map(TFrom from)
where TFrom : class
where TTo : class, new()
{
if (from == null) return null;
var to = new TTo();
Find()(from, to);
return to;
}
///
/// Creates a list of destination objects from source objects using a mapping function.
///
/// The source type.
/// The destination type.
/// The source objects.
/// The destination objects.
public List Map(IEnumerable from)
where TFrom : class
where TTo : class, new()
{
if (from == null) return null;
var map = Find();
return new List(from.Select(f => {
var to = new TTo();
map(f, to);
return to;
}));
}
///
/// Creates a list of destination objects from source objects using a mapping function.
///
/// The source type.
/// The destination type.
/// The source objects.
/// The destination objects.
public List MapList(IEnumerable from)
where TFrom : class
where TTo : class, new()
{
if (from == null) return null;
var map = Find();
return from.Select(f => New(map, f)).ToList();
}
///
/// Creates a list of destination objects from source objects using a mapping function.
///
/// The source type.
/// The destination type.
/// The source objects.
/// The destination objects.
public List MapList(IQueryable from)
where TFrom : class
where TTo : class, new()
{
if (from == null) return null;
var map = Find();
return from.Select(f => New(map, f)).ToList();
}
#region ------ Internals ------------------------------------------------------------------
private TTo New(Action map, TFrom f)
where TFrom : class
where TTo : class, new()
{
var to = new TTo();
map(f, to);
return to;
}
///
/// Repository of all known mapping functions.
///
private readonly Dictionary> _maps = new Dictionary>();
#endregion
}
}