有没有办法禁用AutoMapper的异常包装?

时间:2010-11-02 03:32:59

标签: c# exception exception-handling wrapper automapper

我有一个存储库,当它的EntityNotFoundException方法无法在数据库中找到所请求的实体时会抛出GetSingle<T>(int id)。当我在AutoMapper中使用它并发生异常时,我会得到类似的东西:

  

AutoMapperMappingException:尝试将CategoryDTO映射到类别... ---&gt;

     

AutoMapperMappingException:尝试将System.Int32映射到CategoryType ... ---&gt;

     

AutoMapper.MappingException:尝试将System.Int32映射到CategoryType ... ---&gt;

     

EntityNotFoundException:在数据库中找不到ID为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 个答案:

答案 0 :(得分:1)

我认为有条件地包装异常是不好的设计所以我想唯一要做的就是深入到内部异常并找到第一个无自动反应。

答案 1 :(得分:1)

我在我的NArms.AutoMapper库中实现了AutoMapperMappingException展开(参见issue)。它的主要目的是通过提供MapTo&lt;&gt;()扩展方法来减少代码量,该方法可以代替Mapper.Map()。您可以通过NuGet获取。

显然,源代码在GitHub上是available