gpt4 book ai didi

c# - 如何在代码外部定义 AutoMapper 映射,即在 XML 文件中或使用不同的方法进行完全可配置的对象映射?

转载 作者:太空狗 更新时间:2023-10-29 22:26:44 24 4
gpt4 key购买 nike

编辑:最初我打算使用 AutoMapper 来实现我的目标,但我不得不了解到 AutoMapper 并非旨在以这种方式工作。它使您可以创建配置文件,但在我的情况下(完全可配置)我需要为每个参数组合一个配置文件,所以我想出了一种自己的方法,请参阅答案。

从 AutoMapper wiki 我学会了创建一个像

这样的简单映射
    Mapper.CreateMap<CalendarEvent, CalendarEventForm>().ForMember(dest => dest.Title, opt => opt.MapFrom(src => src.Title));
Mapper.CreateMap<CalendarEvent, CalendarEventForm>().ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.EventDate.Date));
Mapper.CreateMap<CalendarEvent, CalendarEventForm>().ForMember(dest => dest.EventHour, opt => opt.MapFrom(src => src.EventDate.Hour));
Mapper.CreateMap<CalendarEvent, CalendarEventForm>().ForMember(dest => dest.EventMinute, opt => opt.MapFrom(src => src.EventDate.Minute));

对于像这样的两个类

public class CalendarEvent
{
public DateTime EventDate;
public string Title;
}

public class CalendarEventForm
{
public DateTime EventDate { get; set; }
public int EventHour { get; set; }
public int EventMinute { get; set; }
public string Title { get; set; }
}

我现在想知道是否有可能在外部定义映射,即在 XML 文件中,例如

<ObjectMapping>
<mapping>
<src>Title</src>
<dest>Tile</dest>
</mapping>
<mapping>
<src>EventDate.Date</src>
<dest>EventDate</dest>
</mapping>
<mapping>
<src>EventDate.Hour</src>
<dest>EventHour</dest>
</mapping>
<mapping>
<src>EventDate.Minute</src>
<dest>EventMinute</dest>
</mapping>

并由此影响 map 的创建(XML 不是必需的,也可以是其他任何东西)。为简单起见,说类型没有问题,所以 src 和 dest 应该相同,否则失败是可以的。这背后的想法是在应该映射什么以及应该映射到哪里方面非常灵活。我正在考虑反射以根据其名称获取属性值,但这似乎行不通。我也不确定这是否有意义,或者我是否遗漏了一些重要的东西,因此非常感谢您的帮助和想法。

最佳答案

最后,我自己实现了原始需求,尽管我并不需要它(需求已更改)。我会在这里提供代码,以防有人需要它(或多或少作为概念证明,因为仍然可以做很多改进)或者对 XML 感兴趣,请记住,XML 容易出错,这种方法的关键组成部分,属性名称和类型必须完全匹配,否则它将无法工作,但是通过一个小的 GUI 来编辑文件,这应该是可以实现的(我的意思是不手动编辑文件)。

我使用了来自 here 的代码和 here并添加了类 PropertyMapping 来存储从 XML 读取的映射,还添加了类 Foo 和 Bar 来创建嵌套数据结构,以便复制到。

无论如何,这里是代码,也许它可以帮助某些人:

主要内容:

public class Program
{
public static void Main(string[] args)
{
// Model
var calendarEvent = new CalendarEvent
{
EventDate = new DateTime(2008, 12, 15, 20, 30, 0),
Title = "Company Holiday Party"
};

MyObjectMapper mTut = new MyObjectMapper(@"SampleMappings.xml");

Console.WriteLine(string.Format("Result MyMapper: {0}", Program.CompareObjects(calendarEvent, mTut.TestMyObjectMapperProjection(calendarEvent))));

Console.ReadLine();
}

public static bool CompareObjects(CalendarEvent calendarEvent, CalendarEventForm form)
{
return calendarEvent.EventDate.Date.Equals(form.EventDate) &&
calendarEvent.EventDate.Hour.Equals(form.EventHour) &&
calendarEvent.EventDate.Minute.Equals(form.EventMinute) &&
calendarEvent.Title.Equals(form.Title);
}
}

映射器实现:

public class MyObjectMapper
{
private List<PropertyMapping> myMappings = new List<PropertyMapping>();

public MyObjectMapper(string xmlFile)
{
this.myMappings = GenerateMappingObjectsFromXml(xmlFile);
}

/*
* Actual mapping; iterate over internal mappings and copy each source value to destination value (types have to be the same)
*/
public CalendarEventForm TestMyObjectMapperProjection(CalendarEvent calendarEvent)
{
CalendarEventForm calendarEventForm = new CalendarEventForm();

foreach (PropertyMapping propertyMapping in myMappings)
{
object originalValue = GetPropValue(calendarEvent,propertyMapping.FromPropertyName);

SetPropValue(propertyMapping.ToPropertyName, calendarEventForm, originalValue);
}

return calendarEventForm;
}
/*
* Get the property value from the source object
*/
private object GetPropValue(object obj, String compoundProperty)
{
foreach (String part in compoundProperty.Split('.'))
{
if (obj == null) { return null; }

Type type = obj.GetType();
PropertyInfo info = type.GetProperty(part);
if (info == null) { return null; }

obj = info.GetValue(obj, null);
}
return obj;
}
/*
* Set property in the destination object, create new empty objects if needed in case of nested structure
*/
public void SetPropValue(string compoundProperty, object target, object value)
{
string[] bits = compoundProperty.Split('.');
for (int i = 0; i < bits.Length - 1; i++)
{
PropertyInfo propertyToGet = target.GetType().GetProperty(bits[i]);

propertyToGet.SetValue(target, Activator.CreateInstance(propertyToGet.PropertyType));

target = propertyToGet.GetValue(target, null);
}
PropertyInfo propertyToSet = target.GetType().GetProperty(bits.Last());
propertyToSet.SetValue(target, value, null);
}

/*
* Read XML file from the provided file path an create internal mapping objects
*/
private List<PropertyMapping> GenerateMappingObjectsFromXml(string xmlFile)
{
XElement definedMappings = XElement.Load(xmlFile);
List<PropertyMapping> mappings = new List<PropertyMapping>();

foreach (XElement singleMappingElement in definedMappings.Elements("mapping"))
{
mappings.Add(new PropertyMapping(singleMappingElement.Element("src").Value, singleMappingElement.Element("dest").Value));
}

return mappings;
}
}

我的模型类:

public class CalendarEvent
{
public DateTime EventDate { get; set; }
public string Title { get; set; }
}

public class CalendarEventForm
{
public DateTime EventDate { get; set; }
public int EventHour { get; set; }
public int EventMinute { get; set; }
public string Title { get; set; }
public Foo Foo { get; set; }
}

public class Foo
{
public Bar Bar { get; set; }

}

public class Bar
{
public DateTime InternalDate { get; set; }

}

内部映射表示:

public class PropertyMapping
{
public string FromPropertyName;
public string ToPropertyName;

public PropertyMapping(string fromPropertyName, string toPropertyName)
{
this.FromPropertyName = fromPropertyName;
this.ToPropertyName = toPropertyName;
}
}

示例 XML 配置:

<?xml version="1.0" encoding="utf-8" ?>
<ObjectMapping>
<mapping>
<src>Title</src>
<dest>Title</dest>
</mapping>
<mapping>
<src>EventDate.Date</src>
<dest>EventDate</dest>
</mapping>
<mapping>
<src>EventDate.Hour</src>
<dest>EventHour</dest>
</mapping>
<mapping>
<src>EventDate.Minute</src>
<dest>EventMinute</dest>
</mapping>
<mapping>
<src>EventDate</src>
<dest>Foo.Bar.InternalDate</dest>
</mapping>
</ObjectMapping>

关于c# - 如何在代码外部定义 AutoMapper 映射,即在 XML 文件中或使用不同的方法进行完全可配置的对象映射?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19179459/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com