J'ai commencé à utiliser https://github.com/robconery/massive pour un projet. Je me demande s'il existe un outil de mappage permettant de prendre en charge le mappage de type dynamique/statique?
J'ai déjà utilisé AutoMapper. Est-ce qu'AutoMapper prend cela en charge?
Je connais la fonction DynamicMap d’AutoMapper, mais j’estime que cette fonction permet d’exécuter des cartes sans créer d’abord la Carte. Dans mon exemple ci-dessous, cela ne fonctionne pas.
dynamic curUser = users.GetSingleUser(UserID);
var retUser = Mapper.DynamicMap<UserModel>(curUser);
users.GetSingleUser(UserID); // returns a dynamic object
AutoMapper 4.2.0 supporte maintenant Mappage dynamique/expando/dictionary
Avec cette fonctionnalité, vous pouvez mapper vos objets expando sur des types statiques:
dynamic CurUser = _users.GetSingleUser(UserID);
var config = new MapperConfiguration(cfg => { });
var mapper = config.CreateMapper();
var retUser = mapper.Map<UserModel>(CurUser);
Les anciennes versions d'AutoMapper ne prennent pas cela en charge (Massive utilise en interne ExpandoObject
qui ne précise pas les propriétés dont il dispose), et vous avez raison, Mapper.DynamicMap
permet d'effectuer un mappage sans créer de configuration.
En fait, écrire un mappeur n’est pas difficile si vous voulez juste un mappage simple:
public static class DynamicToStatic
{
public static T ToStatic<T>(object expando)
{
var entity = Activator.CreateInstance<T>();
//ExpandoObject implements dictionary
var properties = expando as IDictionary<string, object>;
if (properties == null)
return entity;
foreach (var entry in properties)
{
var propertyInfo = entity.GetType().GetProperty(entry.Key);
if(propertyInfo!=null)
propertyInfo.SetValue(entity, entry.Value, null);
}
return entity;
}
}
dynamic CurUser = _users.GetSingleUser(UserID);
var retUser = DynamicToStatic.ToStatic<UserModel>(CurUser);
Essayez Slapper.AutoMapperhttps://github.com/randyburden/Slapper.AutoMapper
Slapper.AutoMapper mappe des données dynamiques à des types statiques
Cela fonctionne à la fois pour dynamic
et Dictionary<A, B>
, ce qui est génial.
Voici un exemple (tiré de l'URL ci-dessus) montrant avec quelle facilité il fonctionne avec Dictionary:
public class Person
{
public int Id;
public string FirstName;
public string LastName;
}
[Test]
public void CanMapMatchingFieldNamesWithEase()
{
// Arrange
var dictionary = new Dictionary<string, object>
{
{ "Id", 1 },
{ "FirstName", "Clark" },
{ "LastName", "Kent" }
};
// Act
var person = Slapper.AutoMapper.Map<Person>( dictionary );
// Assert
Assert.NotNull( person );
Assert.That( person.Id == 1 );
Assert.That( person.FirstName == "Clark" );
Assert.That( person.LastName == "Kent" );
}
En supposant que la structure que vous utilisez renvoie ExpandoObject
, vous pouvez réaliser une sorte de mappage dynamique à l'aide d'AutoMapper:
Mapper.CreateMap<ExpandoObject, UserModel>()
.ForAllMembers((options) => options.ResolveUsing((resolution) =>
{
var dictionary = (IDictionary<string, object>) resolution.Context.SourceValue;
return dictionary[resolution.Context.MemberName];
}));
...
dynamic CurUser = _users.GetSingleUser(UserID);
var retUser = Mapper.Map<UserModel>(CurUser);
Vous pouvez créer tout type de mappage complexe à l'aide des méthodes ConstructUsing
.
Objet unique:
Mapper.Map<Product>(dynamicProduct);
Liste:
Mapper.Map<List<Product>>(dynamicListOfProducts);
Exemple (ligne 71): https://github.com/AutoMapper/AutoMapper/blob/master/src/UnitTests/DynamicMapping.cs