2013-03-11 5 views
11

Gibt es sowieso Automapper, um alle Eigenschaften eines bestimmten Typs zu ignorieren? Wir versuchen, die Qualität unseres Codes zu verbessern, indem wir die Automapper-Mappings validieren, aber .Ignore() für alle IEnumerable<SelectListItem> setzen müssen, die immer manuell erstellt werden, erzeugt Reibung und verlangsamt Entwicklung.Automapper - Alle Elemente von IEnumerable ignorieren <SelectListItem>

Irgendwelche Ideen?

Mögliche Idee nach Zuordnungen zu erstellen:

var existingMaps = Mapper.GetAllTypeMaps(); 
    foreach (var property in existingMaps) 
    { 
     foreach (var propertyInfo in property.DestinationType.GetProperties()) 
     { 
      if (propertyInfo.PropertyType == typeof(List<SelectListItem>) || propertyInfo.PropertyType == typeof(IEnumerable<SelectListItem>)) 
      { 
       property.FindOrCreatePropertyMapFor(new PropertyAccessor(propertyInfo)).Ignore(); 
      } 
     } 
    } 

Antwort

17

AutoMapper derzeit nicht unterstützt Typ basiert Eigenschaft ignoriert.

Derzeit gibt es drei Möglichkeiten, Objekte zu ignorieren:

  • die Ignore() Optionen verwenden, wenn Ihr Mapping

    Mapper.CreateMap<Source, Dest>() 
        .ForMember(d => d.IgnoreMe, opt => opt.Ignore()); 
    

    Schaffung dieses ist, was Sie vermeiden wollen.

  • Beschriften auf die Ihre IEnumerable<SelectListItem> Eigenschaften mit der die IgnoreMapAttribute

  • Wenn Ihr IEnumerable<SelectListItem> Eigenschaftsnamen eine Namenskonvention folgen. Z.B. alle sie mit dem Wort beginnen "Select" Sie die AddGlobalIgnore Methode verwenden, können sie global zu ignorieren:

    Mapper.Initialize(c => c.AddGlobalIgnore("Select")); 
    

    aber mit diesem können Sie nur mit Starts übereinstimmen mit.

Allerdings können Sie eine convinience Erweiterungsmethode für die ersten Optionen erstellen, die automatisch die Eigenschaften eines bestimmten Typs ignorieren, wenn Sie CreateMap nennen:

public static class MappingExpressionExtensions 
{ 
    public static IMappingExpression<TSource, TDest> 
     IgnorePropertiesOfType<TSource, TDest>(
     this IMappingExpression<TSource, TDest> mappingExpression, 
     Type typeToIgnore 
     ) 
    { 
     var destInfo = new TypeInfo(typeof(TDest)); 
     foreach (var destProperty in destInfo.GetPublicWriteAccessors() 
      .OfType<PropertyInfo>() 
      .Where(p => p.PropertyType == typeToIgnore)) 
     { 
      mappingExpression = mappingExpression 
       .ForMember(destProperty.Name, opt => opt.Ignore()); 
     } 

     return mappingExpression; 
    } 
} 

Und Sie können es mit der folgenden Art und Weise verwenden :

Mapper.CreateMap<Source, Dest>() 
    .IgnorePropertiesOfType(typeof(IEnumerable<SelectListItem>)); 

es wird also noch keine globale Lösung sein, aber Sie müssen die richtigen nicht auflisten, welche Eigenschaften müssen ignoriert werden und es funktioniert für mehr Krawatten vom selben Typ.

Wenn Sie nicht Angst, Ihre Hände schmutzig zu machen:

Derzeit gibt es eine sehr hacky Lösung, die ganz tief in die Interna von AutoMapper geht.Ich weiß nicht, wie die öffentliche diese API ist so diese Lösung könnte Bremse im Merkmal:

Sie können TypeMapCreated Veranstaltung auf der ConfigurationStore ‚s abonnieren

((ConfigurationStore)Mapper.Configuration).TypeMapCreated += OnTypeMapCreated; 

und den Typ hinzufügen, basierend ignorieren direkt am erstellt TypeMap Instanzen:

private void OnTypeMapCreated(object sender, TypeMapCreatedEventArgs e) 
{ 
    foreach (var propertyInfo in e.TypeMap.DestinationType.GetProperties()) 
    { 
     if (propertyInfo.PropertyType == typeof (IEnumerable<SelectListItem>)) 
     { 
      e.TypeMap.FindOrCreatePropertyMapFor(
       new PropertyAccessor(propertyInfo)).Ignore(); 
     } 
    } 
} 
+0

Danke yeah Ich hatte AddGlobalIgnore gefunden, wollte es aber am Typ machen. IgnorePropertiesOfType sieht gut aus danke. Nur nervig müssen wir es zu Hunderten von VMs hinzufügen. Es gibt also keine Möglichkeit, alle abgebildeten Modelle zu durchsuchen und über Reflektion Eigenschaften mit dem Typ von IEnumerable zu finden und dann das ignore-Attribut anzuwenden. – GraemeMiller

+0

Um Attribute dynamisch hinzuzufügen, werden Sie etwas, das IL wie Postharp injiziert. Ich habe jedoch eine ziemlich schmutzige/hacky golbal Lösung gefunden. Ich werde meine Antwort aktualisieren. – nemesv

+0

Yeah sah nur auf die Quelle. Ich sah, wo GlobalIgnore eingezogen wurde, dachte daran, die Quelle für uns zu ändern, aber dies sieht so aus, als würde es den Trick machen! Danke – GraemeMiller

0

Wenn Sie über diese jetzt kommen, scheint es dort eine andere Art und Weise ist.

Mapper.Initialize(cfg => 
{ 
    cfg.ShouldMapProperty = pi => pi.PropertyType != typeof(ICommand); 
}); 

Ich habe nicht untersucht, wenn dies eingeführt wurde. Dies scheint zu blockieren oder zuzulassen, wie auch immer Sie dies filtern. Siehe auch: AutoMapper Configuration

Verwandte Themen