Automapper - Value Resolver с проблемой обобщения - PullRequest
0 голосов
/ 24 января 2019

Я использую 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));

Есть ли обходной путь для этого, или, возможно, я мог бы использовать другой шаблон?

1 Ответ

0 голосов
/ 24 января 2019

Я использовал ConstructServicesUsing совершенно неправильно.

Требуется функция, где Type - тип ValueResolver, который я хочу разрешить, а Object - разрешенный экземпляр. Вы должны вернуть null для типов, которые вы не хотите разрешать.

Так это выглядит по линиям:

cfg => cfg.ConstructServicesUsing(type => type == typeof(MyValueResolver<B>) ? new MyValueResolver<B>(service) : null));

Благодарность за этот ответ отправляется @LucianBargaoanu.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...