Я использую Automapper с нашим основным приложением asp net. Для сопоставлений типа A
-> B
и A
-> C
мне нужен внешний сервис для ввода некоторых дополнительных данных. Поэтому я написал ValueResolver<T>
, где T
равно либо B
, либо C
. Поскольку в C # нет оператора OR
для типов, здесь я использую обобщенный T
.
Для ясности, мой преобразователь значений выглядит так:
public class MyValueResolver<T>: IValueResolver<A, T, string>
{
private readonly IMyService _service;
public MyValueResolver(IMyService service)
{
_service = service;
}
public string Resolve(A source, T destination, string destMember, ResolutionContext context)
{
// do something using only source and _service.
return ...;
}
}
Теперь, в моем стартапе я регистрирую Autopper, как это services.AddAutoMapper();
. Поэтому, когда я использую его где-либо в своем приложении, мне просто нужно вставить IMapper
в конструктор, и он автоматически разрешит MyValueResolver
с IMyService
зависимостью.
Проблема возникает в тестах, когда я не использую DI, и мне нужны и MyValueResolver<B>
, и MyValueResolver<C>
. Я попробовал следующее:
var mappingConfig = new MapperConfiguration(cfg => {
cfg.AddProfile(new MappingProfile());
cfg.ConstructServicesUsing(MyValueResolver =>
new MyValueResolver<B>(service));
cfg.ConstructServicesUsing(MyValueResolver =>
new MyValueResolver<C>(service));
});
var mapper = new Mapper(mappingConfig);
Но это не работает, так как он пытается использовать последний оператор для обоих случаев и завершается неудачно с ошибкой, что он не может привести MyValueResolver<C>
к MyValueResolver<B>
. Но метод не принимает типы с определенными обобщениями (я предполагаю, что это ограничение C #?), Как это cfg.ConstructServicesUsing(MyValueResolver<C> => new MyValueResolver<C>(service));
Есть ли обходной путь для этого, или, возможно, я мог бы использовать другой шаблон?