将对象转换为泛型类型-automapper静态扩展

本文关键字:-automapper 静态 扩展 泛型类型 对象 转换 | 更新日期: 2023-09-27 18:24:07

我正在尝试将我的AutoMapper代码转换为更流畅的api,例如。现有代码:

Model.Foo target = Mapper.Map<Contract.Foo, Model.Foo>(source);

我希望代码看起来像这个

Model.Foo target = source.ConvertTo<Model.Foo>();

我开始写我的扩展方法,但我似乎无法让它发挥作用。

public static class AutoMapperConverterExtension
{
    public static T ConvertTo<T>(this string source) where T : new()
    {
        Type sourceType = Type.GetType(source); 
        if (IsMapExists<sourceType, T>()) // complains here! cannot resolve 'sourceType'. If I use inline, won't compile.
        {
            return Mapper.Map<T>(source);    
        }
        throw new NotImplementedException("type not supported for conversion");
    }
    public static bool IsMapExists<TSource, TDestination>()
    {
        return (AutoMapper.Mapper.FindTypeMapFor<TSource, TDestination>() != null);
    }        
}

将对象转换为泛型类型-automapper静态扩展

看起来你过于复杂了,你可能可以逃脱:

public static T ConvertTo<T>(this object source)
{
    return Mapper.Map<T>(source);
}

也就是说,你不能在发布的代码中使用泛型。sourceType是一个运行时变量,不能用于在编译时确定的泛型类型参数。在这种特殊情况下,AutoMapper提供了一个可以使用的FindTypeMapFor()的非通用版本。

您也不能假设source将是一个字符串参数。你可能想要object

public static T ConvertTo<T>(this object source) where T : new()
{
    Type sourceType = Type.GetType(source); 
    if (IsMapExists(sourceType, typeof(T)))
    {
        return Mapper.Map<T>(source);
    }
    throw new NotImplementedException("type not supported for conversion");
}
public static bool IsMapExists(Type source, Type destination)
{
    return (AutoMapper.Mapper.FindTypeMapFor(source, destination) != null);
}

在调用泛型函数时,抛出错误的行需要更改为使用反射。

var method = typeof(AutoMapperConverterExtension).GetMethod("IsMapExists");
var generic = method.MakeGenericMethod(sourceType, typeof(T));
bool exists = Convert.ToBoolean(generic.Invoke(null, null));
if (exists) 
{
    return Mapper.Map<T>(source);    
}

如何使用反射来调用泛型方法?