我想将抽象类型的任意列表映射到共享相同基本类型的任意属性集. 这是一些UnitTest代码,当前失败了,我想成功.您能帮我一个通用的解决方案吗?
I'd like to map an arbitrary list of abstract types to an arbitrary set of properties, that share the same base type. Here is some UnitTest code, which currently fails and which I want to success. Could you help me, get a generic solution?
以下是课程:
public class Source { public string Name { get; set; } = "SomeName"; public Dictionary<string, ValueType> SourceList { get; set; } = new Dictionary<string, ValueType>(); } public interface IDestination { string Name { get; set; } } public class Destination : IDestination //And many other classes like this, with other properties inherited from ValueType { public string Name { get; set; } public double DoubleValue { get; set; } public int IntValue { get; set; } public string SomeOtherProperty { get; set; } }这是单元测试,我想成功:
And here is the unit test, I'd like to succeed:
[TestMethod] public void TestMethod1() { var source = new Source(); source.SourceList.Add("IntValue", (int) 3); source.SourceList.Add("DoubleValue", (double) 3.14); Mapper.Initialize(config => { //Put in some magic code here!!! }); var destinationAbstract = Mapper.Map<Source, IDestination>(source); //the type of destination is known only at runtime. Therefore Mapping to Interface var destination = (Destination) destinationAbstract; Assert.AreEqual(source.Name, destination.Name); Assert.AreEqual((int)source.SourceList["IntValue"], destination.IntValue); Assert.AreEqual((double)source.SourceList["DoubleValue"], destination.DoubleValue); }请注意,
- 从IDestination继承的类数仅在运行时知道
- 对于每个Source-instance,SourceList的内容可能有所不同,因此目标类的属性也可能针对每个类定义而更改
我希望您能为我提供帮助,因为我无法借助文档确定通用解决方案.
I hope you can help me, because I wasn't able to determine a generic solution with the help of the documentation.
谢谢.
推荐答案考虑了Lucians提示并尝试使用Automapper进行其他操作之后,我终于找到了用于初始单元测试的解决方案:
After considering Lucians hint and after trying different things with Automapper, I finally found a solution for my initial unit-test:
[TestMethod] public void TestMethod1() { var source = new Source(); source.SourceList.Add("IntValue", (int) 3); source.SourceList.Add("DoubleValue", (double) 3.14); Mapper.Initialize(config => { //"Magic code" config.CreateMap<Source, IDestination>(); config.CreateMap(typeof(Source), typeof(Destination)).IncludeBase(typeof(Source), typeof(IDestination)); }); //standard map-call var destination = Mapper.Map<Destination>(source); //Additional "Trick": Dictionary<string, object> mappingDict = source.SourceList.ToDictionary(pair => pair.Key, pair => (object) pair.Value); Mapper.Map(mappingDict, destination, typeof(Dictionary<string, object>), typeof(Destination)); Assert.AreEqual(source.Name, destination.Name); Assert.AreEqual(source.SourceList["IntValue"], destination.IntValue); Assert.AreEqual(source.SourceList["DoubleValue"], destination.DoubleValue); }技巧"是将我的Dictionary<string, ValueType>强制转换为Dictionary<string,object>,并将此字典成员映射到标准(map)调用的additional(!)中. 这可行,但有一些缺点:
The "trick" is to cast my Dictionary<string, ValueType> to Dictionary<string,object> and to map this dictionary-member to the destination object in addition(!) to the standard map-call. This works, but has some drawbacks:
在我看来,没有其他方法可以解决我的最初问题.但我愿意提出任何建议或对我的解决方案进行改进. 通过使用反射也可以轻松解决最初的问题,因此应该存在用于适当映射设置的所有信息,但是我找不到这种适当的映射设置.
It seems to me, that there is no other way to solve my initial problem. But I am open for any suggestions or improvements to my solution. The initial problem could be solved also easily through using reflections, so all information for a proper mapping setup should be existent, but I was not able to find this proper mapping setup.
更多推荐
自动映射器:列出成员
发布评论