使用AutoMapper时,将日志添加到目标对象

时间:2016-06-08 10:24:02

标签: c# .net automapper

使用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;

2 个答案:

答案 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的操作。这适用于所有标记类型,您不必专门为该案例编写每个对象。

基于反射的差异代码将处理您需要的所有日志记录,以保持对象与实现代码保持一致。