Search code examples
c#asp.netgenericsautomapper

AutoMapper - Create one mapping for all generic class usages


I have an OverridableValue<T> class to represent a value that can be manually overriden (Contains a T Value prop and a boolean for whether it's manual or not). This class is in use in my internal model, and in my API I have a DTO that should just hold the value without consideration for if it's manual or not. So for example let's say I use these classes:

public class Test
{
    public OverridableValue<string> Prop1 { get; set; }
    public OverridableValue<int> Prop2 { get; set; }
}

public class TestDTO
{
    public string Prop1 { get; set; }
    public int Prop2 { get; set; }
}

Now I want to use the AutoMapper to create a mapping between the Test class and the TestDTO class. I can do this:

CreateMap<OverridableValue<string>, string>().ConvertUsing(o => o.Value);
CreateMap<OverridableValue<int>, int>().ConvertUsing(o => o.Value);
CreateMap<Test, TestDTO>();

and this will work, but I don't want to add a line for each possible generic usage of the OverridableValue class. I was wondering if there is way to create a single mapping for every single usage. Basically, I want something like this:

CreateMap<OverridableValue<T>, T>().ConvertUsing(o => o.Value);

Is there a way to do something like this?


Solution

  • Thanks to @LucianBargaoanu for the answer: Instead of adding a mapping line for each possible type, the solution was to add an implicit conversion in the OverridableValue<T> class:

    public static implicit operator T(OverridableValue<T> overridableValue) => overridableValue.Value;
    

    That worked for 99% of the cases. The only issue after that was specifically in converting OverridableValue<string> to a string. In this case the AutoMapper decided to use the class's ToString() method instead of doing an implicit conversion. So to fix this I also overridden the ToString method:

    public override string ToString()
    {
        return Value.ToString();
    }