1

I'm working on a very dynamic Silverlight Application where viewmodels are dynamic models. The WCF service returns a Response object that contains enough information (TableName property and an Dictionary[] array containing entities).

So, suppose I have a single entity (Dictionary) and some instance of viewmodel that is an object of any kind. The key of the dictionary serves as the property name, and obviously, the value will be used to set the property value in the viewmodel. I need to map values from this dictionary to values of the dynamic viewmodel and vice-versa. In order to have some constraints on this mappings, I created interfaces to validate the values of the dictionary, so I only get/set values if the values propertynames are defined in the contract.

I know about duck typing, dynamic proxies, object mappers, and I know how to use reflection.

I started to searching for some tool or framework that can turn this task easy. So I've found Impromptu-Interface. I'm trying to do this with 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>();
}

Works like a charm.

And the reverse mapping:

  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;
}

The question is: Is there any better way to do this ?

Jone Polvora
  • 2,184
  • 1
  • 22
  • 33
  • I think your text would fit with your question *"What is the best way to map from/to a Dictionary with objects properties based on an interface as contract?"* if you put your solution as one of the answers, instead of changing the question to *"Is there any better way to do this?"* – jbtule Jan 31 '13 at 17:00
  • @jbtule Hello, sorry my poor english. Didn't getting your comment... Anyway, I tried Impromptu.InvokeSetAll(target, proxy) but throws exception. In therms of performance, is there a better way to map values contained in any object to a dictionary, respecting an interface contract ? – Jone Polvora Jan 31 '13 at 17:20
  • `Impromptu.InvokeSetAll` "Invoke with dictionary, anonymous type or named arguments." (or list of tuples) to describe what should be set, and in the code it's going to be looping like you are already. So not a better way in terms of performance. – jbtule Jan 31 '13 at 17:49

1 Answers1

0

You should be able to just use LINQs ToDictionary method instead of the foreach. For a collection, it just takes a lambda that shows it how to get a key.

Mathieson
  • 1,698
  • 2
  • 17
  • 19
  • It's not possible to use LINQ since i'm working with raw dynamic objects that I don't know the structure in design time. – Jone Polvora Feb 04 '13 at 20:52
  • 1
    Is the structure known at compile time - i.e. are these strongly typed objects? If so, you should be able to do the following: `var result = properties.Select(propertyName => new{value = Impromptu.InvokeGet(proxy, propertyName), propertyName = propertyName}).ToDictionary(v => v.propertyName);` – Mathieson Feb 14 '13 at 16:45