Внедрить из ExpandoObject с помощью ValueInjecter
Я использую ValueInjecter для сопоставления объектов, и я пытаюсь внедрить из ExpandoObject. Я нашел пример инъекции из динамического.
public class Ac
{
public string Aa { get; set; }
}
[Test]
public void Aa()
{
var o = new { Aa = "aa" };
dynamic d = o;
var a = new Ac{ Aa = "bb" };
a.InjectFrom((object)d);
Assert.AreEqual(o.Aa, a.Aa);
}
Но мне не удалось заставить его работать с ExpandoObject. Как я могу это сделать?
2 ответа
Решение
using System;
using System.Collections.Generic;
using System.Dynamic;
using Omu.ValueInjecter;
namespace ConsoleApplication7
{
public class FromExpando : KnownSourceValueInjection<ExpandoObject>
{
protected override void Inject(ExpandoObject source, object target)
{
var d = source as IDictionary<string, object>;
if (d == null) return;
var tprops = target.GetProps();
foreach (var o in d)
{
var tp = tprops.GetByName(o.Key);
if (tp == null) continue;
tp.SetValue(target, o.Value);
}
}
}
public class Foo
{
public string Name { get; set; }
public int Ace { get; set; }
}
class Program
{
static void Main(string[] args)
{
dynamic x = new ExpandoObject();
x.Ace = 1231;
x.Name = "hi";
var f = new Foo();
//f.InjectFrom<FromExpando>((object) x); // edit:compilation error
new FromExpando().Map((object)x,f);
Console.WriteLine(f.Ace);
Console.WriteLine(f.Name);
}
}
}
Я использовал тот же подход, что и Omu, опубликовавший чтение из ExpandoObject, который приходит из XML. Поскольку все свойства представлены как "строка", я немного подправил ответ @Omu, используя метод "Convert.ChangeType":
public class FromExpando : KnownSourceValueInjection<ExpandoObject>
{
protected override void Inject(ExpandoObject source, object target)
{
var d = source as IDictionary<string, object>;
if (d == null) return;
var tprops = target.GetProps();
foreach (var o in d)
{
var tp = tprops.GetByName(o.Key);
if (tp == null) continue;
var newValue = Convert.ChangeType(o.Value, tp.PropertyType);
tp.SetValue(target, newValue);
}
}
}