Есть ли способ отключить перенос исключений AutoMapper? - PullRequest
6 голосов
/ 02 ноября 2010

У меня есть хранилище, которое выдает EntityNotFoundException, когда его GetSingle<T>(int id) метод не может найти запрошенную сущность в базе данных.Когда я использую это с AutoMapper и возникает исключение, я получаю что-то вроде этого:

AutoMapperMappingException: при попытке сопоставить CategoryDTO с Category ... --->

AutoMapperMappingException:Попытка сопоставить System.Int32 с CategoryType ... --->

AutoMapper.MappingException: Попытка сопоставить System.Int32 с CategoryType ... --->

EntityNotFoundException: сущностьТип CategoryType с идентификатором 5 не найден в базе данных

Мое пользовательское исключение на 4 уровня ниже.Это затрудняет использование блоков try-catch, потому что теперь мне нужно сделать что-то вроде этого:

try
{
    // do the mapping
}
catch (AutoMapperMappingException e)
{
    // get the inner-most exception
    while (e.InnerException != null)
    {
        e = e.InnerException;
    }

    // check to see if it's an EntityNotFoundException
    if (e.GetType() == typeof (EntityNotFoundException))
    {
        var notFound = e as EntityNotFoundException;
        // do something specific here, like inform the user
    }
    else
    {
        // do something more generic
    }

То, что я хотел бы сделать, это просто:

try
{
    // do the mapping
}
catch (EntityNotFoundException e)
{
    // do something specific here, like inform the user
}
catch (Exception e)
{
    // do something more generic
}

Есть ли способ отключить поведение AutoMapper для переноса исключений, чтобы я получал исключительные ситуации, которые создаются?

Ответ

В итоге я создал тонкую оболочку вокруг AutoMapperкоторый поймает AutoMapperMappingException, найдет самое внутреннее исключение и выдаст следующее:

public class AutoMapperWrapper
{
    public TB Map<TA, TB>(TA source, TB destination)
    {
        // try to do the mapping
        try
        {
            return Mapper.Map(source, destination);
        }
        // catch AutoMapper's exception
        catch (Exception e)
        {
            // find the first InnerException that's not wrapped
            while (e is AutoMapperMappingException)
            {
                e = e.InnerException;
            }

            // if the inner exception is null, throw the original exception
            if (e == null)
            {
                throw;
            }
            // otherwise, throw the inner exception
            else
            {
                throw e;
            }
        }
    }
}

Недостатком этого метода является то, что иногда полезно посмотреть все дерево исключений, чтобы увидеть, какое свойствоили сопоставление сущностей AutoMapper не удалось, но этот код даст вам только самое внутреннее исключение, которое иногда само по себе не очень полезно, например InvalidCastException: «не удалось преобразовать строку в int», но не сообщит вам, какиесобственности это было.

Ответы [ 2 ]

1 голос
/ 08 апреля 2014

Я реализовал развертывание AutoMapperMappingException в моей библиотеке NArms.AutoMapper (см. выпуск ).Основное назначение - уменьшить объем кода, предоставив метод расширения MapTo <> (), который можно использовать вместо Mapper.Map ().Вы можете получить его через NuGet .

Очевидно, что исходный код доступен на GitHub.

1 голос
/ 23 декабря 2010

Я полагаю, что было бы неплохо создать условную оболочку исключения, поэтому я думаю, что единственное, что нужно сделать, - это углубиться во внутреннее исключение и найти первое нет autopperexception.

...