I have several extension methods with same name and different receiving argument:
public static List<T>? MapTo<T>(this List<ClassA_DataModel> data) where T : ClassA_BusinessModel, new() { ... }
public static List<T>? MapTo<T>(this List<ClassB_DataModel> data) where T : ClassB_BusinessModel, new() { ... }
... (+50)
used to mapp (1:1
) between different DataModels to their corresponding BusinessModels (EDIT1), and need to use reflection to invoke the right method according to the List<MyClassX_DataModel> passed as parameter:
var businessObjects = (typeof(MapperModel)?.GetMethod(nameof(MapperModel.MapTo))?.MakeGenericMethod(businessModelType).Invoke(null, new[] { dataObjects }) as IList)?.Cast<object>().ToList();
The problem is that I get an Exception because there are more than one method with the same name:
System.Reflection.AmbiguousMatchException: 'Ambiguous match found'
My guess would be to do something like this:
var myMethod = typeof(MapperModel)?.GetMethods().FirstOrDefault(m => m.Name == nameof(MapperModel.MapTo) && m.XXXX == businessModelType);
var businessObjects = (myMethod.MakeGenericMethod(businessModelType).Invoke(null, new[] { dataObjects }) as IList)?.Cast<object>().ToList();
but I don't know how to get the comparision part to work, provided that I have to match a List<BusinessModel>
.
EDIT
I have to use generics for the methods, instead of just declaring my methods like this (without the use of generics):
public static List< ClassA_BusinessModel>? MapTo(this List<ClassA_DataModel> data) { ... }
because I will later be also invoking on a Dictionary where a lot of different data models will be listed:
public static List<T>? MapTo<T>(this Dictionary<Type, IList> dataset) where T : Class36_BusinessModel, new() { ... }
This way I will manage providing a mapping from different DataModels
to one BusinessModel
(n:1
):
List<Class17_DataModel> data17 = (...)
List<Class23_DataModel> data23 = (...)
(...)
var dataset = new Dictionary<Type, IList>()
{
[Class17_DataModel] = data17,
[Class23_DataModel] = data23,
(...)
}
var business17 = data.MapTo<Class17_BusinessModel>();
var business36 = dataset.MapTo<Class36_BusinessModel>();
Any suggestion?
Thanks in advance!
I found a workaround to solve my question. First I get all methods matching my given name
var methods= (typeof(MapperModel)?.GetMethods().Where(x => x.Name == nameof(MapperModel.MapTo);
and then I try-catch invoking every method with the types and parameters I am interested in in each case:
var listType = typeof(List<>).MakeGenericType();
var dictType = typeof(Dictionary<,>).MakeGenericType(Type, IList);
The try-catch will throw an exception for those methods on which I will try invoking types and/or parameters for which they are not intended for, but this suits for the moment as a workaround solution. I would anyway be happier with something like
var myMethod= (typeof(MapperModel)?.GetMethods().Single(m => m.Name == nameof(MapperModel.MapTo) && m.XXXXXXX== listInst?.GetType());
var myMethod= (typeof(MapperModel)?.GetMethods().Single(m => m.Name == nameof(MapperModel.MapTo) && m.XXXXXXX== dictInst?.GetType());