1

Я работаю над очень динамичным приложением Silverlight, где viewmodels являются динамическими моделями. Служба WCF возвращает объект Response, который содержит достаточно информации (свойство TableName и массив Dictionary [], содержащий объекты).Каков наилучший способ отображения из/в словарь с объектами на основе интерфейса в качестве контракта?

Итак, предположим, что у меня есть единое целое (словарь) и некоторый экземпляр viewmodel, который является объектом любого рода. Ключ словаря служит именем свойства, и, очевидно, значение будет использоваться для установки значения свойства в модели view. Мне нужно отобразить значения из этого словаря в значения динамической модели просмотра и наоборот. Чтобы иметь некоторые ограничения на эти сопоставления, я создал интерфейсы для проверки значений словаря, поэтому я получаю/устанавливаю значения, только если имена свойств определены в контракте.

Я знаю о наборе уток, динамических прокси, объектных картографах, и я знаю, как использовать отражение.

Я начал искать какой-то инструмент или фреймворк, который легко превратит эту задачу. Итак, я нашел Impromptu-Interface. Я пытаюсь сделать это с помощью интерфейса Impromptu:

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

Возникает вопрос: Есть ли лучший способ сделать это?

+0

Я думаю, что ваш текст будет соответствовать вашему вопросу * «Каков наилучший способ сопоставления из/в словарь с объектами на основе интерфейса как контракта?» *, Если вы поместите свое решение в качестве одного из ответов, вместо этого меняя вопрос на вопрос: «Есть ли лучший способ сделать это?» * – jbtule

+0

@jbtule Здравствуйте, извините, мой плохой английский. Не получил ваш комментарий ... Во всяком случае, я попробовал Impromptu.InvokeSetAll (target, proxy), но выбрал исключение. В условиях производительности есть ли лучший способ сопоставления значений, содержащихся в любом объекте, со словарем, с учетом контракта на интерфейс? –

+0

'Impromptu.InvokeSetAll'" Вызывать со словарем, анонимным типом или именованными аргументами. " (или список кортежей), чтобы описать, что должно быть установлено, а в коде это будет цикл, как вы уже. Так что не лучший способ с точки зрения производительности. – jbtule

ответ

0

Вы должны просто использовать метод LINQs ToDictionary вместо foreach. Для коллекции просто требуется лямбда, которая показывает, как получить ключ.

+0

Невозможно использовать LINQ, так как я работаю с необработанными динамическими объектами, которые не знаю структуру во время разработки. –

+1

Является ли структура известной во время компиляции, т. Е. Эти сильно типизированные объекты? Если это так, вы должны сделать следующее: 'var result = properties.Select (propertyName => new {value = Impromptu.InvokeGet (прокси, propertyName), propertyName = propertyName}). ToDictionary (v => v.propertyName); ' – Mathieson

+0

хороший пункт. Благодарю. –

Смежные вопросы