3

このパターン/アプローチが以前に使用されているのを見たことがあり、既存のコードの一部をより効率的にするために再作成しようとしています。

ユース ケース: ソース システムから複雑なオブジェクトが取得されます。クライアントは情報のサブセットのみを使用するため、JSON シリアライゼーションのためにこの複雑なオブジェクトを単純な POCO に「マップ」する必要があります。さらに、このマッピング方法では、他のデータのフォーマットが行われます。まず、複雑なオブジェクトを、いくつかの基本的な処理を行うジェネリック メソッドに渡します。

// 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 に答える