С помощью простого инжектора это может быть связано с определением реализации универсального преобразователя, которая позволяет отображать из списка источников в список назначений, например:
public class ListMapper<TSource, TDestination>
: IMapper<List<TSource>, List<TDestination>>
{
private readonly IMapper<TSource, TDestination> mapper;
public ListMapper(IMapper<TSource, TDestination> mapper) => this.mapper = mapper;
public List<TDestination> Map(List<TSource> source) =>
source.Select(this.mapper.Map).ToList();
}
Вы можете зарегистрировать этот преобразователь следующим образом:
container.Register(typeof(IMapper<,>), MapperAssemblies);
container.Register(typeof(IMapper<,>), typeof(ListMapper<,>));
// Register last
container.RegisterConditional(typeof(IMapper<,>), typeof(DefaultMapper<,>),
Lifestyle.Singleton,
c => !c.Handled);
Обратите внимание, как ListMapper<,>
реализует IMapper<List<TSource>, List<TDestination>>
?Это имеет тот же эффект, что и ограничение универсального типа, что позволяет Simple Injector применять условно маппер.
И если вы действительно хотите проявить фантазию и хотите иметь возможность сопоставить любой произвольный тип коллекции с любым другимДля произвольного типа коллекции можно определить следующий универсальный сопоставитель:
public class EnumerableMapper<TIn, TInCollection, TOut, TOutCollection>
: IMapper<TInCollection, TOutCollection>
where TInCollection : IEnumerable<TIn>
where TOutCollection : IEnumerable<TOut>, new()
{
private readonly IMapper<TIn, TOut> mapper;
public EnumerableMapper(IMapper<TIn, TOut> mapper) => this.mapper = mapper;
public TOutCollection Map(TInCollection source) => ...;
}
Несмотря на то, что этот класс содержит два дополнительных универсальных типа поверх абстракции IMapper
, Simple Injector по-прежнему может выяснить, что всетипы должны быть.Вы можете зарегистрировать этот тип следующим образом:
container.Register(typeof(IMapper<,>), typeof(EnumerableMapper<,,,>));
Единственная сложная задача - правильно реализовать метод Map
, что может быть пугающим, поскольку тип возвращаемого значения может быть что угодно , которое реализуетIEnumerable<T>
, хотя вы все еще сможете его создать.