3

我以前见过这种模式/方法,我正在尝试重新创建它以使我现有的一些代码更有效率。

用例: 从源系统中检索复杂对象。客户端只会使用一部分信息,因此我们必须将这个复杂的对象“映射”到一个简单的 POCO 以进行 JSON 序列化;此外,在这种映射方法中,还完成了一些其他数据格式化。首先,我们将复杂对象传递给一个通用方法,该方法进行一些基本处理

// 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
    }
}
4

2 回答 2

2

我不太确定你在问什么,但是你想要这样的东西吗?

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

称为:

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

(注意论点中缺少的())。

于 2013-02-12T15:26:12.763 回答
0

看起来你可以在这里实现代理模式。否则,可能会将逻辑移动到实际对象本身,并在每个知道如何序列化自身的 ComplexObjects 中添加一个 ToJSON() 方法。然后将它们附加在一起以构成 JSON 数组。这将取决于您使用什么来序列化 JSON,因此在下面的示例中,我只是手动完成了它。

常见的 JSONSerializable 接口

    public interface IJsonSerializable
    {
        string ToJson();
    }

复杂和简单的对象:

    public class ComplexObjectA : IJsonSerializable
    {
        public string ToJson()
        {
            var simpleObject = new SimpleObjectA();

            // Map away

            // Then serialize
            return SerializeDTO(simpleObject);
        }

        private string SerializeDTO(SimpleObjectA simpleObject)
        {
            throw new NotImplementedException();
        }
    }

    public class SimpleObjectA
    {
        // simple properties
    }

然后是入口点

        static void GenericEntry<T, TK>(string userid, string environment, DBContext context)
        {

            // Magic happens here
            var results = GetResults();

            // More magic

            var resultList = new List<string>();
            foreach (var row in results)
            {
                var poco = row.ToJson();
                resultList.Add(poco);
            }
            return String.Format("[{0}]", String.Join(resultList, ", "));
        }
于 2013-02-12T15:43:02.960 回答