J'ai une interface publique que j'essaie de mapper deux énumérations différentes l'une à l'autre. J'ai essayé d'utiliser le code suivant:
Mapper.CreateMap<Contract_1_1_0.ValidationResultType, Common.ValidationResultType>();
Quand ça n'a pas marché, j'ai essayé:
Mapper.CreateMap<Contract_1_1_0.ValidationResultType, Common.ValidationResultType>().ConvertUsing(x => (Common.ValidationResultType)((int)x));
Mais cela ne semble pas fonctionner non plus. Existe-t-il de toute façon un automappeur pour gérer ce scénario?
Vous n'avez pas besoin de créer CreateMap pour les types d'énumération. Débarrassez-vous simplement de l'appel CreateMap et cela devrait fonctionner, tant que les noms et/ou les valeurs correspondent entre les types d'énumération.
Alternativement à l'écriture de convertisseurs personnalisés, utilisez simplement ConvertUsing ()
Mapper.CreateMap<EnumSrc, EnumDst>().ConvertUsing(value =>
{
switch(value)
{
case EnumSrc.Option1:
return EnumDst.Choice1;
case EnumSrc.Option2:
return EnumDst.Choice2;
case EnumSrc.Option3:
return EnumDst.Choice3;
default:
return EnumDst.None;
}
});
Mon Automapper fonctionne de cette façon:
Si je crée une carte: Automapper fera correspondre les énumérations par valeur, même si le nom correspond parfaitement.
Si je ne crée pas de carte: Automapper fera correspondre les énumérations par leur nom.
La manière la plus simple que j'ai trouvée pour moi est la suivante:
Mon Enum est imbriqué dans une autre classe, donc j'utilise la méthode ForMember et MapFrom comme ci-dessous:
Mapper.CreateMap<ProblematicCustomer, ProblematicCustomerViewModel>()
.ForMember(m=> m.ProblemType, opt=> opt.MapFrom(x=> (ProblemTypeViewModel)(int)x.ProblemType))
.ForMember(m=> m.JudgmentType, opt=> opt.MapFrom(x=> (JudgmentTypeViewModel)(int)x.JudgmentType));
ProblemType et JudgmentType sont des énumérations. Et leurs modèles de vue associés sont ProblemTypeViewModel et JudgmentTypeViewModel avec les mêmes membres que leurs modèles associés.
Bien que je ne teste pas, mais je pense que la ligne ci-dessous devrait fonctionner pour vous:
Mapper.CreateMap<Contract_1_1_0.ValidationResultType, Common.ValidationResultType>()
.ForMember(m=> m, opt => opt.MapFrom(x=> (Common.ValidationResultType)(int)x);
J'espère que ça aide.
Créez simplement un mappeur pour deux Enums, c'est tout! Automapper mappera par la valeur correspondante ou la valeur d'index de l'énumération. (par exemple, Brouillon -> Étape 1)
public enum SourceStatus
{
Draft,
Submitted,
Deleted
}
public enum DestinationStatus
{
Step1,
Step2,
Step3
}
public class SourceObj
{
public SourceStatus Status { get; set; }
}
public class DestinationObj
{
public DestinationStatus Status { get; set; }
}
class Program
{
static void Main(string[] args)
{
//Static APi style - this is obsolete now. From Version 5.0 onwards this will be removed.
SourceObj mySrcObj = new SourceObj();
mySrcObj.Status = SourceStatus.Deleted;
Mapper.CreateMap<SourceStatus, DestinationStatus>();
Mapper.CreateMap<SourceObj, DestinationObj>();
DestinationObj myDestObj = Mapper.Map<SourceObj, DestinationObj>(mySrcObj);
//New way of doing it
SourceObj mySrcObj2 = new SourceObj();
mySrcObj2.Status = SourceStatus.Draft;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<SourceObj, DestinationObj>();
});
IMapper mapper = config.CreateMapper();
var source = new SourceObj();
var dest = mapper.Map<SourceObj, DestinationObj>(source);
}
}
Les autres réponses ici n'ont pas fonctionné pour moi.
Vous devez créer une classe qui implémente:
ITypeConvertor<SourceType ,DestinationType>
Donc, à titre d'exemple
Mapper.CreateMap<EnumType1.VatLevel, EnumType2.VatRateLevel>()
.ConvertUsing(new VatLevelConvertor());
Et la classe:
internal class VatLevelConvertor : ITypeConverter<EnumType1.VatLevel, EnumType2.VatRateLevel>
{
public EnumType2.VatRateLevel Convert(ResolutionContext context)
{
EnumType1.VatLevel value = (EnumType1.VatLevel)context.SourceValue;
switch (value)
{
case EnumType1.VatLevel.Standard:
return EnumType2.VatRateLevel.Normal;
case EnumType1.VatLevel.Reduced:
return EnumType2.VatRateLevel.Lower;
case EnumType1.VatLevel.SuperReduced:
return EnumType2.VatRateLevel.Other;
default:
return EnumType2.VatRateLevel.Other;
}
}
}
Voici une possibilité pour effectuer une conversion entre deux types Enum qui ont tous deux des valeurs différentes, tout en utilisant AutoMapper. Dans mon cas, j'avais besoin d'utiliser AutoMapper car les types Enum étaient des propriétés sur d'autres entités converties par AutoMapper; l'utilisation d'AutoMapper pour ces entités était une exigence.
La première étape consiste à installer la configuration du mappeur comme suit:
Mapper.CreateMap<EnumSrc, EnumDst>()
.ConstructUsing(EnumConversion.FromSrcToDst);
L'appel de .ConstructUsing(...)
nous permet de passer dans notre propre méthode pour faire la conversion. La méthode de conversion est assez simple:
public class EnumConversion
{
internal static EnumDst FromSrcToDst(ResolutionContext arg)
{
EnumSrc value = (EnumSrc)arg.SourceValue;
switch(value)
{
case EnumSrc.Option1:
return EnumDst.Choice1;
case EnumSrc.Option2:
return EnumDst.Choice2;
case EnumSrc.Option3:
return EnumDst.Choice3;
default:
return EnumDst.None;
}
}
}
Nous avons simplement switch
à travers les valeurs de l'énumération source et renvoyons arbitrairement la valeur Enum de destination appropriée. AutoMapper s'occupe du reste.
J'essayais de mapper entre des énumérations "égales" en utilisant Automapper, mais malheureusement cela n'a pas fonctionné. Je soupçonne que le problème est une différence de boîtier:
public enum Foo {
val1,
val2
}
public enum Bar {
Val1,
Val2
}
Foo
est quelque chose généré automatiquement à partir d'un XSD, et le fournisseur est nul. Il y a aussi une trentaine de valeurs et je ne voulais pas mettre un switch
aussi grand n'importe où pour quelque chose de si idiot.
L'approche que j'ai adoptée était de convertir la valeur source en chaîne et de l'analyser en tant que valeur de destination:
static Foo ConvertEnum(Bar source)
{
Foo result;
var parsed = Enum.TryParse(source.ToString().ToLowerInvariant(), true, out result);
if(!parsed)
// throw or return default value
throw new ArgumentOutOfRangeException("source", source, "Unknown source value");
return result;
}
Bien sûr, cela ne fonctionne que si vos énumérations n'ont que des différences de boîtier. Vous pouvez le rendre plus élaboré en nettoyant la chaîne d'entrée (par exemple, supprimez les traits de soulignement, etc.) ou en y ajoutant des éléments si nécessaire.