2013-06-11 5 views
0

Я пытаюсь преобразовать словарь в привязанность к интерфейсу.Преобразование словаря в интерфейс

Я могу получить словарь для объекта в порядке. Делая что-то вроде этого:

public static class ObjectExtensions 
{ 
    public static T ToObject<T>(this IDictionary<string, object> source) 
    where T : class, new() 
    { 
     var someObject = new T(); 
     var someObjectType = someObject.GetType(); 

     foreach (var item in source) 
     { 
      someObjectType.GetProperty(item.Key).SetValue(someObject, item.Value, null); 
     } 

     return someObject; 
    } 

    public static IDictionary<string, object> AsDictionary(this object source, BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance) 
    { 
     return source.GetType().GetProperties(bindingAttr).ToDictionary 
     (
      propInfo => propInfo.Name, 
      propInfo => propInfo.GetValue(source, null) 
     ); 

    } 
} 

var dictionary = new Dictionary<string, object> {{"Prop1", "hello world!"}, {"Prop2", 3893}}; 
var someObject = dictionary.ToObject<A>(); 

Но я хочу, чтобы иметь возможность:

var someObject = dictionary.ToObject<iA>(); 

Любой знает, как это можно сделать?

+1

Для меня было ужасно писать метод расширения объекта без уважительной причины. –

+0

Вы на самом деле просто пытаетесь сделать сериализацию? Если это так, есть намного более простые способы. Например. найдите DataContractSerializer для XML или Json.NET для JSON. –

+0

Если вы пытаетесь разработать это для модульного тестирования, вам может потребоваться использовать существующую фальшивую инфраструктуру, такую ​​как Moq. Эти рамки уже имеют поддержку для создания классов «на лету», которые реализуют интерфейс, и вы можете легко создать вспомогательный метод, который конвертирует словарь в последовательность вызовов Moq Setup. –

ответ

1

Вам понадобится создать конкретную реализацию этого интерфейса. Вы можете сделать это, используя TypeBuilder class.

В качестве альтернативы можно использовать динамический тип и Impromptu

using ImpromptuInterface; 
using ImpromptuInterface.Dynamic; 

public interface IMyInterface 
{ 
    string Prop1 { get; } 
} 

//Anonymous Class 
var anon = new { 
     Prop1 = "Test", 
} 

var myInterface = anon.ActLike<IMyInterface>(); 

мне нравится решение Ого намного лучше, хотя. Оба вышеизложенного гораздо сложнее, однако их можно сделать, не заставляя вызывающего абонента указывать конкретный конкретный тип.

+0

Я не знаю, мог ли Castle DynamicProxy (http://www.castleproject.org/projects/dynamicproxy/) соответствовать, но я использовал его для подобных прецедентов, таких как mixins. – Pragmateek