Вы можете применить родовые c ограничения в BaseEntityMap<TSource, TTarget>
классе к вашим BaseSource
и BaseTarget
классам (или применить ограничения в IEntityMapper<in TSource, out TTarget>
интерфейсе и избавиться от базового абстрактного класса)
abstract class BaseEntityMap<TSource, TTarget> : IEntityMapper<TSource, TTarget>
where TSource : BaseSource
where TTarget : BaseTarget
{
public abstract TTarget Map(TSource entity);
}
Затем объявите словарь картографов, как показано ниже, используя Func<BaseSource, BaseTarget>
делегат. Все должно быть в порядке, поскольку вы ограничили объявление BaseEntityMap<TSource, TTarget>
и Func<in T, out TResult>
, поддерживающее контравариацию для входного параметра и ковариацию для результата
IDictionary<Type, Func<BaseSource, BaseTarget>> MappersMap = new Dictionary<Type, Func<BaseSource, BaseTarget>>();
public Workflow()
{
var orderMapper = new OrderEntityMapper();
MappersMap.Add(typeof(SourceEntityA), source => orderMapper.Map((SourceEntityA)source));
var goodsMapper = new GoodsEntityMapper();
MappersMap.Add(typeof(SourceEntityC), source => goodsMapper.Map((SourceEntityC)source));
//....more mappers
}
и пример выполнения
foreach (var entity in entities)
{
//Need to handle this situations with correct covariations.
var target = mapper(entity);
//.... code continues
}