样本类:
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;
再次更新......
识别TestClass
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;
}
}
答案 0 :(得分:1)
请参阅MSDN article抽象类。
对你来说重要的是:
无法实例化抽象类。
您需要映射到其中一个派生类,或从基类中删除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);