我试图将我的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);
}
}
答案 0 :(得分:4)
看起来你的事情过于复杂,你可能会逃脱:
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);
}
答案 1 :(得分:2)
抛出错误的行需要更改为在调用泛型函数时使用反射。
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);
}