【问题标题】:What is the best way to map from/to a Dictionary with objects properties based on an interface as contract?将基于接口的对象属性映射到字典的最佳方法是什么?
【发布时间】:2013-01-31 15:35:53
【问题描述】:

我正在开发一个非常动态的 Silverlight 应用程序,其中视图模型是动态模型。 WCF 服务返回一个包含足够信息(TableName 属性和包含实体的 Dictionary[] 数组)的 Response 对象。

所以,假设我有一个实体(字典)和一些视图模型实例,它是任何类型的对象。字典的键作为属性名称,显然,该值将用于设置视图模型中的属性值。我需要将此字典中的值映射到动态视图模型的值,反之亦然。为了对这个映射有一些限制,我创建了接口来验证字典的值,所以我只有在合同中定义了值属性名时才获取/设置值。

我了解鸭子类型、动态代理、对象映射器,并且知道如何使用反射。

我开始寻找一些可以使这项任务变得简单的工具或框架。所以我找到了Impromptu-Interface。我正在尝试使用 Impromptu-interface 来做到这一点:

  public static TContract MapFromDictionary<TContract>(object bindingModel, Dictionary<string, object> data) where TContract : class {
  var proxy = new ImpromptuDictionary(data).ActLike<TContract>();
  var properties = Impromptu.GetMemberNames(proxy);
  foreach (var propertyName in properties) {
    object value = Impromptu.InvokeGet(proxy, propertyName);
    Impromptu.InvokeSet(bindingModel, propertyName, value);
  }
  return bindingModel.ActLike<TContract>();
}

像魅力一样工作。

以及反向映射:

  public static Dictionary<string, object> MapToDictionary<TContract>(object source) where TContract : class {
  var proxy = source.ActLike<TContract>();
  var result = new Dictionary<string, object>();
  var properties = Impromptu.GetMemberNames(proxy);

  foreach (var propertyName in properties) {
    object value = Impromptu.InvokeGet(proxy, propertyName);
    result.Add(propertyName, value);
  }

  return result;
}

问题是:有没有更好的方法来做到这一点?

【问题讨论】:

  • 我认为您的文本将适合您的问题“从/映射到具有基于接口作为合同的对象属性的字典的最佳方法是什么?” 如果您将您的解决方案作为答案之一,而不是将问题更改为“有没有更好的方法来做到这一点?”
  • @jbtule 你好,对不起我的英语不好。没有收到您的评论...无论如何,我尝试了 Impromptu.InvokeSetAll(target, proxy) 但抛出异常。在性能方面,有没有更好的方法将任何对象中包含的值映射到字典,尊重接口契约?
  • Impromptu.InvokeSetAll "使用字典、匿名类型或命名参数调用。" (或元组列表)来描述应该设置的内容,并且在代码中它将像你一样循环。所以在性能方面不是更好的方法。

标签: c# silverlight automapper system.reflection impromptu-interface


【解决方案1】:

您应该能够只使用 LINQs ToDictionary 方法而不是 foreach。对于一个集合,它只需要一个 lambda 来显示它如何获取密钥。

【讨论】:

  • 不可能使用 LINQ,因为我正在使用我不知道设计时结构的原始动态对象。
  • 结构在编译时是否已知 - 即这些是强类型对象吗?如果是这样,您应该能够执行以下操作:var result = properties.Select(propertyName =&gt; new{value = Impromptu.InvokeGet(proxy, propertyName), propertyName = propertyName}).ToDictionary(v =&gt; v.propertyName);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多