Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Action delegate to call correct function based on generic type

I have seen this pattern/approach used before, and I'm trying to recreate it to make some of my existing code more efficient.

The Use Case: A complex object is retrieved from a source system. Only a subset of the information will be used by the client, so we must 'map' this complex object to a simple POCO for JSON serialization; additionally, in this mapping method, some other data formatting is done. First, we pass our complex object into a generic method that does some basic processing

// Generic Method, Entry Point for mapping
static void GenericEntry<T, TK>(string userid, string environment, DBContext context) {

    .... // do stuff with userid and environment to set a context
    .... // query results, which return a complex object of Type TK

    // Here is where I would like to use an Action delegate to call the appropriate map
    // method.. there could hundreds of objects that map and process down to a POCO, 
    // Currently, this logic is using reflection to find the appropriate method with 
    // the appropriate signature... something like: 
    Type functionType = typeof(DTOFunctions);
    var methods = functionType.GetMethods(BindingFlags.Public | BindingFlags.Static);
    var mi = methods.FirstOrDefault(x => x.Name == "MapObject" && 
        x.ReturnType == typeof(T));

    if (mi == null) throw new ArgumentException(string.Format("Unable to find method MapObject for {0}", typeof(TK).Name));

    var resultList = new ArrayList();
    foreach (var row in results)
    {
        var poco = mi.Invoke(functionType, new object[] { row });
        resultList.Add(poco);
    }
    if (resultCount == -1) resultCount = resultList.Count;
    return SerializeDTO(resultList, ResponseDataTypes.JSON, resultCount);

    // THERE HAS TO BE A BETTER WAY STACKOVERFLOW! HALP!
} 

public Class DTOFunctions {
    // Mapping Method from Complex to Simple object
    static SimplePOCO_A MapObject(ComplexObject_A cmplx){
        var poco = new SimplePOCO_A(); 
        .... // mapping from cmplx field to SimplePOCO field
    }

    static SimplePOCO_B MapObject(ComplexObject_B cmplx) {
        var poco = new SimplePOCO_B(); 
        .... // mapping from cmplx field to SimplePOCO fiel
    }
}
like image 714
AnthonyAlmighty Avatar asked Aug 13 '26 13:08

AnthonyAlmighty


1 Answers

I'm not quite sure what you're asking, but is something like this what you want?

static void GenericEntry<T, TK>(string userid, string environment, 
                                DBContext context, Func<T, TK> conversion) 
{
    //....
    var resultList = new List<TK>();
    foreach (var row in results)
    {
        var poco = conversion(row);
        resultList.Add(poco);
    }
    //....
}

Called as:

 GenericEntry<ComplexObject, SimplePOCO>(userid, environment, context, DTOFunctions.MapObject)

(Note the lack of () in the argument).

like image 195
Bobson Avatar answered Aug 15 '26 04:08

Bobson