2010-11-27 4 views
0

Je crée une application ASP.NET MVC 2 en C# et j'utilise avec succès Automapper pour mapper les valeurs entre ViewModels et les objets métier.Utilisation de Automappper pour mapper aux méthodes

En plus de plusieurs propriétés explicites, mes objets métier enveloppent un dictionnaire comme un tout catch pour les propriétés qui ne sont pas explicitement définies. Quelque chose de semblable à:

public class MyBusinessObject { 
    public void SetExtraPropertyValue<T>(string key, T value) { 
     // ... 
     } 
    public T GetExtraPropertyValue<T>(string key, T defaultValue) { 
     // ... 
     } 
} 

Dans mon ViewModel, j'ai la liberté de créer des propriétés que je veux, mais je ne peux pas modifier les objets métier.

Alors disons que je crée un modèle de vue comme celui-ci:

class MyViewModel { 
    public string CustomProp { get; set; } 
} 

et la valeur que je veux stocker et récupérer devront utiliser

businessModelInstance.SetExtraPropertyValue("CustomProp", newVal); 

et

businessModelInstance.GetExtraPropertyValue("CustomProp"); 

J'ai des problèmes dans les deux sens.
Tout d'abord, lors du passage du MyBusinessObject au MyViewModel, je pense qu'il devrait être simple à faire dans mon profil personnalisé Automapper:

CreateMap<MyBusinessObject, MyViewModel>() 
    .ForMember(dest => dest.CustomProp, 
      opt => opt.MapFrom(s => s.GetExtraPropertyValue("CustomProp", ""))); 

Cependant, MyBusinessObject.CustomProp est jamais peuplée, bien que d'autres propriétés sont.
Deuxièmement, je ne sais pas comment configurer obtenir une valeur de MyViewModel.CustomProp pour appeler MyBusinessObject.SetExtraPropertyValue.

  • Existe-t-il un moyen d'effectuer cette correspondance avec Automapper?
  • Y a-t-il une attaque complètement différente que j'essaierais? ?
  • Dois-je utiliser le mappage manuel dans mon contrôleur? Par exemple, MyBusinessObject.SetExtraPropertyValue("CustomProp", MyViewModel.CustomProp)


MISE À JOUR: Voici ma solution basée sur les suggestions de @Patrick Steele: J'ai ajouté un attribut personnalisé aux propriétés du modèle de vue que je voulais mapper les clés de propriété supplémentaires. Un TypeConverter personnalisé utilise la réflexion pour trouver ces attributs et mapper les propriétés de manière appropriée.

public class ItemExtraPropertyConverter : ITypeConverter<MyViewModel, MyBusinessObject> 
{ 
    public MyBusinessObject Convert(ResolutionContext context) 
    { 
     var destination = context.DestinationValue as MyBusinessObject; 
     if (destination == null) 
      throw new InvalidOperationException("Destination type is not of type MyBusinessObject"); 

     foreach (var property in context.SourceType.GetProperties()) 
      foreach (var attribute in property.GetCustomAttributes(true).OfType<ExtraPropertyAttribute>()) 
      { 
       var key = attribute.Key; 
       if (string.IsNullOrEmpty(key)) 
        key = property.Name; 
       destination.SetExtraPropertyValue(key, property.GetValue(context.SourceValue, null)); 
      } 

     return destination; 
    } 
} 

public class ExtraPropertyAttribute : Attribute 
{ 
    public ExtraPropertyAttribute() 
    { 
    } 
    public ExtraPropertyAttribute(string key) 
    { 
     Key = key; 
    } 

    public string Key { get; set; } 
} 

public class MyViewModel 
{ 
    [ExtraProperty] 
    public string CustomProp { get; set; } 

    [ExtraProperty("OtherPropertyValue")] 
    public string CustomProp2 { get; set; } 
} 

Dans la méthode de configuration de profil classe personnalisée:

CreateMap<MyViewModel, MyBusinessObject>() 
      .ConvertUsing<ItemExtraPropertyConverter>(); 

Répondre

0

Je pense que quelque chose ne va pas avec votre implémentations GetExtraPropertyValue et SetExtraPropertyValue. J'ai jeté ensemble un test rapide et la cartographie que vous avez fournie ci-dessus a fonctionné comme prévu. Voici la mise en œuvre que j'ai utilisé pour le test:

+0

merci d'avoir pris le temps de s'y intéresser. vous avez raison, le test simple a fonctionné pour moi. doit être quelque chose de stupide dans mon code - c'est quelque chose que je peux déboguer. Le plus gros problème pour moi est de savoir comment aller dans l'autre sens - mappage des propriétés sur le modèle de vue à l'entrée de dictionnaire appropriée sur l'objet métier.Je n'ai toujours pas été capable de trouver une solution ... Des idées là-bas? – jaminto

+1

Je pense qu'un travail de convertisseur de type personnalisé fonctionne pour cela. Un peu de réflexion pour interroger votre modèle de vue pour l'ensemble de ses propriétés publiques. Utilisez le nom de la propriété en tant que clé pour vos appels à SetPropertyValue. Il suffit de réaliser que la réflexion a un impact sur la performance - vous devrez décider si c'est un impact acceptable. – PatrickSteele

+0

Il ne s'agit pas d'un site à volume élevé (un site d'administration), donc la réflexion n'est pas un problème. Merci de m'avoir indiqué la bonne direction. – jaminto

Questions connexes