![](/img/trans.png)
[英]Convert ExpandoObject String Property to DateTime using Automapper
[英]Convert ExpandoObject to abstract object using Automapper
樣本類別:
public abstract class SomeBase
{
protected int _x = 100;
public abstract int X { get; }
protected int _y = 200;
public abstract int Y { get; }
}
public class SomeBody : SomeBase
{
public override int X { get { return _x + 10; } }
public override int Y { get { return _y + 20; } }
private int _z = 300;
public int Z { get { return _z + 30; } }
}
public class SomeOne : SomeBase
{
public override int X { get { return _x - 10; } }
public override int Y { get { return _y - 20; } }
private int _a = 300;
public int A { get { return _a - 30; } }
}
對象到ExpandoObject方法:
public static ExpandoObject ToExpandoObject<T>(this T target)
{
var jsonSerializerSettings = new JsonSerializerSettings();
jsonSerializerSettings.Converters.Add(new StringEnumConverter());
var json = JsonConvert.SerializeObject(target, Formatting.Indented, jsonSerializerSettings);
var expandoObject = JsonConvert.DeserializeObject<ExpandoObject>(json, new ExpandoObjectConverter());
return expandoObject;
}
將ExpandoObject轉換為抽象對象:
//someBase
//X = 110, Y = 220, Z = 330
SomeBase someBase = new SomeBody();
//someOne
//X = 90, Y = 180, A = 270
dynamic someOne = new SomeOne().ToExpandoObject();
Mapper.Initialize(cfg =>
{
cfg.CreateMap<SomeBase, SomeBase>();
});
//I want
//someBase
//X = 90, Y = 180, A = 270
Mapper.Map<ExpandoObject, SomeBase>(someOne, someBase);
但是會發生錯誤。
無法創建抽象類的實例
我們如何處理這個問題?
AutoMapper版本為6.02
*由於英語不成熟,請考慮使用Google翻譯器。
更新:
我知道抽象。
我只想知道AutoMapper是否可以執行以下操作:
SomeBody someBody = new SomeBody();
//someBase
//X = 110, Y = 220, Z = 330
SomeBase someBase = someBody;
SomeOne someOne = new SomeOne();
//someBase
//X = 90, Y = 180, A = 270
someBase = someOne;
再次更新...
測試類
public class TestClass
{
public int IntValue { get; set; }
public SomeBase SomeBase { get; set; }
}
我的最終目標是:
var testClass = new TestClass();
testClass.IntValue = 10;
testClass.SomeBase = new SomeBody();
dynamic expandoObject = testClass.ToExpandoObject();
expandoObject.SomeBase = new SomeOne().ToExpandoObject();
Mapper.Initialize(cfg =>
{
cfg.CreateMap<TestClass, TestClass>();
});
///Mapping the expandoObject object that changed the property to the testClass object again
///My expectation is that the type of SomeBase Property in testClass is SomeOne.
Mapper.Map<ExpandoObject, TestClass>(expandoObject, testClass);
非常感謝您用不足的英語和不足的幫助來幫助我。
我的解決方案
var testClass = new TestClass();
testClass.IntValue = 10;
testClass.SomeBase = new SomeBody();
dynamic expandoObject = testClass.ToExpandoObject();
expandoObject.SomeBase = new SomeOne().ToExpandoObject();
Mapper.Initialize(cfg =>
{
cfg.CreateMap<ExpandoObject, SomeBase>().ConvertUsing(new SomeBaseConverter());
cfg.CreateMap<FirstItem, FirstItem>();
});
Mapper.Map<ExpandoObject, TestClass>(expandoObject, testClass);
Debug.WriteLine(testClass.SomeBase.GetType().ToString());
///"Sample.Common.Models.SomeOne"
SomeBaseConverter:
public class SomeBaseConverter : ITypeConverter<object, SomeBase>
{
public SomeBase Convert(dynamic source, SomeBase destination, ResolutionContext context)
{
var dictionary = source as IDictionary<string, object>;
if (dictionary.ContainsKey("Z"))
{
var someBody = new SomeBody();
var config = new MapperConfiguration(cfg => cfg.CreateMap<ExpandoObject, SomeBody>());
config.CreateMapper().Map(source, someBody);
destination = someBody;
}
else
{
var someOne = new SomeOne();
var config = new MapperConfiguration(cfg => cfg.CreateMap<ExpandoObject, SomeOne>());
config.CreateMapper().Map(source, someOne);
destination = someOne;
}
return destination;
}
}
請參閱MSDN文章重新抽象類。
對您來說重要的部分是:
抽象類無法實例化。
您需要映射到派生類之一,或者從基類中刪除abstract修飾符。
如果您有靜態類型的對象,則AutoMapper非常有用。 它很好地處理了多態:
Mapper.CreateMap<SomeBase1, SomeBase2>()
.Include<SomeBody1, SomeBody2>()
.Include<SomeOne1, SomeOne2>();
Mapper.CreateMap<SomeBody1, SomeBody2>();
Mapper.CreateMap<SomeOne1, SomeOne2>();
// for a single object:
SomeBase1 source = GetDatum();
SomeBase2 = Mapper.Map<SomeBase1, SomeBase2>();
// for an IEnumerable:
IEnumerable<SomeBase1> source = GetData();
IEnumerable<SomeBase2> = Mapper.Map<IEnumerable<SomeBase1>, IEnumerable<SomeBase2>>(source);
但是您正在使用ExpandoObject,因此更加困難。 如果您可以通過ExpandoObject中的數據來區分所需的類,則可以嘗試如下操作:
Mapper.CreateMap<ExpandoObject, SomeBase>()
.ConstructUsing((ExpandoObject input) => {
if (input.X == 5)
{
return new SomeOne();
}
else
{
return new SomeBody();
}
});
然后在Mapper.Map<Expandoobject, SomeBase>(...)
起作用之前使用的代碼。 否則,您可以專門告訴它要映射到的類型: Mapper.DynamicMap<SomeBody>(someOne);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.