0

I'm trying to convert my AutoMapper code to be more fluent-api like, e.g. existing code:

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

What I'd like the code to look like is this

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

I started writing my extension method, but I can't seem to get this to work.

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);
    }        
}
Raymond
  • 3,382
  • 5
  • 43
  • 67

2 Answers2

4

It looks like you are over-complicating things, and you might be able to get away with:

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

That said, you can't use generics as you are attempting to do in the code code as posted. sourceType is a runtime variable, and cannot be used for a generic type argument, which is determined at compile time. In this particular case, AutoMapper provides a non-generic version of FindTypeMapFor() that you can use.

You also cannot assume that source is going to be a string parameter. You probably want an 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);
}
Steve Czetty
  • 6,147
  • 9
  • 39
  • 48
2

The line throwing the error needs to change to use reflection when calling the generic function.

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);    
}

How do I use reflection to call a generic method?

Community
  • 1
  • 1
Ismail Hawayel
  • 2,167
  • 18
  • 16
  • thank you, I learned something new, but I marked the other answer as correct as it better solves the problem I was facing. – Raymond Sep 22 '14 at 21:40