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

Add log to destination object when using AutoMapper

使用 AutoMapper 时是否可以将日志添加到目标对象?

如果我有两个对象:

class A
{
    int PropertyOne
    int PropertyTwo
    int PropertyThree
    List<string> Log
}

class B
{
    int PropertyOne
    int PropertyTwo
}

当从 B 映射到 A 时,我想为每个 属性 更改自动添加一个日志条目到 A.Log。

例如如果在映射操作期间,两个对象上的 PropertyOne = 3,但 A.PropertyTwo = 1 和 B.PropertyTwo = 2,我想将日志条目添加到 A.Log - 最好是类似"PropertyTwo changed from 1 to 2"

而不是自动 属性,使用 自定义 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 changing value from 0 to 1

PropertyTwo changing value from 0 to 2

您可以实现一个 custom type converter,它可以与名为 IPropertyLogger 的标记接口一起使用。 AutoMapper.

可以显式使用它的任何子类型

类型转换器可以使用反射并在调用默认 AutoMapper 行为之前执行您请求的类似差异的操作。这适用于所有标记类型,您不必为每个对象专门针对这种情况进行编码。

您基于反射的 diff 代码将处理您需要的所有日志记录,使您的对象远离实现代码。