2016-06-08 2 views
1

Можно ли добавить журнал к целевому объекту при использовании AutoMapper?Добавить журнал к объекту назначения при использовании AutoMapper

Если у меня есть два объекта:

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

class B 
{ 
    int PropertyOne 
    int PropertyTwo 
} 

Когда отображение из В в А, я хотел бы, чтобы автоматически регистрационная запись добавляется в A.Log для каждого свойства, которое было изменено.

E.g. если во время операции сопоставления PropertyOne = 3 для обоих объектов, но A.PropertyTwo = 1 и B.PropertyTwo = 2, я хотел бы добавить запись в журнал A.Log - желательно что-то вроде «PropertyTwo изменено с 1 на 2 "

+0

'Automapper' не является основой регистрации. –

+0

Touche! ;-) Тем не менее, я просто хотел бы немного контактировать с его функциональностью ;-) – kennethkryger

ответ

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 изменяя значение от 0 до 1

PropertyTwo изменяя значение от 0 до 2

+0

Нет ли способа сделать AutoMapper этим? Я хотел бы сохранить код котельной таблички в настройках свойств, так как у меня будет много разных объектов, и я хочу только регистрировать изменения, если это будет сделано AutoMapper (и очень хотелось бы избежать необходимости " IsLoggingEnabled "для управления, когда регистрация должна быть включена или нет). – kennethkryger

+0

Вы можете добавить его в Mapper (formember, forallmembers в CreatMap), но он не является обычным (AutoMapper не является службой ведения журнала). – Styxxy

+0

Вы также можете играть с PostSharp (https://www.postsharp.net/), чтобы уменьшить код шаблона. – Styxxy

1

Вы может реализовать custom type converter, который работа с интерфейсом маркера под названием IPropertyLogger. Любой подтип этого может быть явно использован AutoMapper.

Преобразователь типа может использовать отражение и выполнять операцию diff-like, которую вы запрашиваете, перед вызовом поведения по умолчанию AutoMapper. Это будет работать для всех помеченных типов, и вам не нужно будет кодировать каждый объект специально для этого случая.

Ваш код, основанный на отражении, будет обрабатывать все записи, которые вам требуются, чтобы вы не очищали объекты от кода реализации.

Смежные вопросы