2016-06-08 7 views
1

Ist es möglich, dem Zielobjekt ein Protokoll hinzuzufügen, wenn AutoMapper?Protokoll zum Zielobjekt hinzufügen, wenn AutoMapper verwendet wird

Wenn ich zwei Objekte haben:

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

class B 
{ 
    int PropertyOne 
    int PropertyTwo 
} 

Bei der Zuordnung von B nach A, ich möchte automatisch ein Protokolleintrag zu A.Log haben für jede Eigenschaft hinzugefügt, geändert wird.

z. Wenn während einer Mapping-Operation PropertyOne = 3 für beide Objekte ist, aber A.PropertyTwo = 1 und B.PropertyTwo = 2, würde ich gerne einen Protokolleintrag zu A.Log hinzufügen - vorzugsweise etwas wie "PropertyTwo von 1 zu 2 "

+0

'Automapper' ist kein Logging-Framework. –

+0

Touche! ;-) Allerdings würde ich gerne ein bisschen auf seine Funktionalität huckepack machen ;-) – kennethkryger

Antwort

2

Anstatt einer automatischen Eigenschaft erstellen Sie eine Eigenschaft mit einem benutzerdefinierten Setter, in dem Sie einen Eintrag zur Protokollliste hinzufügen.

Beispiel Konsolenanwendung:

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)); 
    } 
} 

Dies wird Leistung:

PropertyOne ändernden Wert von 0 bis 1

PropertyTwo ändernden Wert von 0 bis 2

+0

Gibt es keine Möglichkeit, AutoMapper das zu tun? Ich möchte den Code der Kesselplatte aus den Property Settern heraushalten, da ich viele verschiedene Objekte haben werde und nur Änderungen protokollieren möchte, wenn dies von AutoMapper erledigt wird (und ich würde sehr gerne vermeiden, ein " IsLoggingEnabled "Flag, um zu steuern, wann die Protokollierung aktiviert werden soll oder nicht". – kennethkryger

+0

Sie könnten es in den Mapper (forMember, forallMembers in der CreatMap) hinzufügen, aber es ist überhaupt nicht sauber (AutoMapper ist kein Protokollierprogramm). – Styxxy

+0

Sie können auch mit PostSharp (https://www.postsharp.net/) herumspielen, um den Standardcode zu reduzieren. – Styxxy

1

Sie könnte eine custom type converter implementieren, die würde arbeiten mit einer Marker-Schnittstelle namens IPropertyLogger. Jeder Untertyp davon könnte explizit von AutoMapper verwendet werden.

Der Typkonverter könnte Reflektion verwenden und die von Ihnen angeforderte diff-ähnliche Operation ausführen, bevor das Standardverhalten des AutoMapper aufgerufen wird. Dies würde für alle markierten Typen funktionieren und Sie müssten nicht jedes Objekt speziell für den Fall codieren.

Ihr reflektionsbasierter Diff-Code würde die gesamte Protokollierung verarbeiten, die Sie benötigen, um Ihre Objekte vor Implementierungscode zu schützen.

Verwandte Themen