使用AutoMapper时,是否可以将日志添加到目标对象?
如果我有两个对象:
class A
{
int PropertyOne
int PropertyTwo
int PropertyThree
List<string> Log
}
class B
{
int PropertyOne
int PropertyTwo
}
当从B映射到A时,我想自动为每个被更改的属性添加一个日志条目A.Log。
E.g。如果在映射操作期间,两个对象上的PropertyOne = 3,但A.PropertyTwo = 1且B.PropertyTwo = 2,我希望在A.Log中添加一个日志条目 - 最好是&#34; PropertyTwo从1更改为2&#34;
答案 0 :(得分:2)
使用自定义 setter创建一个属性,而不是自动属性,在该setter中将条目添加到日志列表中。
示例控制台应用程序:
public static class Program
{
public class A
{
private int _PropertyOne;
private int _PropertyTwo;
private int _PropertyThree;
public int PropertyOne
{
get { return _PropertyOne; }
set
{
if (value == _PropertyOne)
return;
Log.Add(string.Format("PropertyOne changing value from {0} to {1}", _PropertyOne, value));
_PropertyOne = value;
}
}
public int PropertyTwo
{
get { return _PropertyTwo; }
set
{
if (value == _PropertyTwo)
return;
Log.Add(string.Format("PropertyOne changing value from {0} to {1}", _PropertyTwo, value));
_PropertyTwo = value;
}
}
public int PropertyThree
{
get { return _PropertyThree; }
set
{
if (value == _PropertyThree)
return;
Log.Add(string.Format("PropertyOne changing value from {0} to {1}", _PropertyThree, value));
_PropertyThree = value;
}
}
public List<string> Log { get; private set; }
public A()
{
Log = new List<string>();
}
}
public class B
{
public int PropertyOne { get; set; }
public int PropertyTwo { get; set; }
}
public static void Main(string[] args)
{
AutoMapper.Mapper.Initialize(cfg =>
{
cfg.CreateMap<A, B>().ReverseMap();
});
var b = new B() {PropertyOne = 1, PropertyTwo = 2};
var a = AutoMapper.Mapper.Map<B, A>(b);
a.Log.ForEach(s => Console.WriteLine(s));
}
}
这将输出:
PropertyOne将值从0更改为1
PropertyTwo将值从0更改为2
答案 1 :(得分:1)
您可以实现一个custom type converter,它可以使用名为IPropertyLogger
的标记接口。 AutoMapper
可以明确使用任何子类型。
在调用默认的AutoMapper行为之前,类型转换器可以使用反射并执行您请求的类似diff的操作。这适用于所有标记类型,您不必专门为该案例编写每个对象。
基于反射的差异代码将处理您需要的所有日志记录,以保持对象与实现代码保持一致。