基于前述的Mapper类,我们可以定义静态的 Mapper工厂类MapperFactory如下
public static class MapperFactory
{
private static readonly IDictionary<KeyValuePair<Type, Type>, Mapper> Dictionary =
new ConcurrentDictionary<KeyValuePair<Type, Type>, Mapper>();
public static bool Contains<TSource, TDest>()
{
return Dictionary.ContainsKey(new KeyValuePair<Type, Type>(typeof(TSource), typeof(TDest)));
}
public static Mapper<TSource, TDest> CreateOrRetrieveMap<TSource, TDest>() where TDest : class, new()
{
var pair = new KeyValuePair<Type, Type>(typeof(TSource), typeof(TDest));
if (!Dictionary.ContainsKey(pair))
{
Dictionary.Add(new KeyValuePair<KeyValuePair<Type, Type>, Mapper>(pair, new Mapper<TSource, TDest>()));
}
return Dictionary[pair] as Mapper<TSource, TDest>;
}
public static Mapper<TSource, TDest> AddMapperHelper<TSource, TDest>(Mapper<TSource, TDest> mapper) where TDest: class,new()
{
if (!Dictionary.ContainsKey(new KeyValuePair<Type, Type>(typeof(TSource), typeof(TDest))))
{
Dictionary.Add(new KeyValuePair<KeyValuePair<Type, Type>, Mapper>(
new KeyValuePair<Type, Type>(typeof(TSource), typeof(TDest)), mapper));
}
return mapper;
}
public static Mapper<TSource, TDest> AddMap<TSource, TDest>(Action<TSource, TDest> action) where TDest : class, new()
{
var pair = new KeyValuePair<Type, Type>(typeof(TSource), typeof(TDest));
if (!Dictionary.ContainsKey(pair))
{
Dictionary.Add(new KeyValuePair<KeyValuePair<Type, Type>, Mapper>(pair, new Mapper<TSource, TDest>()));
}
var mapper = Dictionary[pair] as Mapper<TSource, TDest>;
mapper.Add(action);
return mapper;
}
public static TDest MapTo<TSource, TDest>(this TSource src) where TDest: class ,new()
{
var mapper = RetrieveOrRegisterMapHelper<TSource, TDest>();
return mapper.Convert(src);
}
public static IList<TDest> MapTo<TSource, TDest>(this IEnumerable<TSource> src) where TDest : class, new()
{
var mapper = RetrieveOrRegisterMapHelper<TSource, TDest>();
return mapper.Convert(src);
}
private static Mapper<TSource, TDest> RetrieveOrRegisterMapHelper<TSource, TDest>() where TDest : class, new()
{
var pair = new KeyValuePair<Type, Type>(typeof(TSource), typeof(TDest));
if (!Dictionary.ContainsKey(pair))
{
var srcRegMethod = typeof(TSource).GetMethod("RegisterMap");
if (srcRegMethod != null && srcRegMethod.IsStatic)
{
srcRegMethod.Invoke(null, null);
}
var destRegMethod = typeof(TDest).GetMethod("RegisterMap");
if (destRegMethod != null && destRegMethod.IsStatic)
{
destRegMethod.Invoke(null, null);
}
if (srcRegMethod == null && destRegMethod == null)
{
AddMapperHelper(new Mapper<TSource, TDest>());
}
}
return Dictionary[pair] as Mapper<TSource, TDest>;
}
}