Словарь <string,string> сопоставить объект с помощью Automapper
Ниже приведен код только для этого вопроса
У меня такой класс, как
public User class
{
public string Name{get;set;}
public string Age{get;set;
}
У меня есть словарь вроде
Dictionary<string,string> data= new Dictionary<string,string>();
data.Add("Name","Rusi");
data.Add("Age","23");
User user= new User();
Теперь я хочу Automapper
объект User
к этому dictionary
с помощью Automapper
. Automapper отображает свойства объектов, но в моем случае есть словарь и объект.
Итак, пожалуйста, предложите мне, как я могу это сделать
Ответы
Ответ 1
AutoMapper сопоставляет свойства объектов и не должен работать в таких сценариях. В этом случае вам нужна магия Reflection. Вы можете обмануть промежуточную сериализацию:
var data = new Dictionary<string, string>();
data.Add("Name", "Rusi");
data.Add("Age", "23");
var serializer = new JavaScriptSerializer();
var user = serializer.Deserialize<User>(serializer.Serialize(data));
И если вы настаиваете на использовании AutoMapper, вы можете, например, сделать что-то вроде:
Mapper
.CreateMap<Dictionary<string, string>, User>()
.ConvertUsing(x =>
{
var serializer = new JavaScriptSerializer();
return serializer.Deserialize<User>(serializer.Serialize(x));
});
а потом:
var data = new Dictionary<string, string>();
data.Add("Name", "Rusi");
data.Add("Age", "23");
var user = Mapper.Map<Dictionary<string, string>, User>(data);
Если вам нужно обрабатывать более сложные иерархии объектов с под-объектами, вы должны задать себе следующий вопрос: является ли Dictionary<string, string>
правильной структурой данных для использования в этом случае?
Ответ 2
AutoMapper - довольно гибкое решение. Вероятно, вы можете достичь этого, используя настраиваемый профиль сопоставления, например:
public class UserMappingProfile : Profile
{
// Props
public override string ProfileName { get { return "UserMappingProfile"; } }
// Methods
public override void Configure()
{
CreateMap<User, Dictionary<string, string>>().ConvertUsing<DictionaryTypeConverter>();
base.Configure();
}
// Types
internal class DictionaryTypeConverter : ITypeConverter<User, Dictionary<string, string>>
{
public User Convert(ResolutionContext context)
{
var dict = context.SourceValue as Dictionary<string, string>;
if (dict == null)
return null;
return new User() { Name = dict["Name"], Age = dict["Age"] };
}
}
}
При этом я могу создать собственный экземпляр mapper:
var config = new Configuration(new TypeMapFactory(), MapperRegistry.AllMappers());
config.AddProfile<UserMappingProfile>();
config.AssertConfigurationIsValid();
var mapper = new MappingEngine(config);
Скорее всего, я могу:
var dict = new Dictionary<string, string> { { "Name", "Matt" }, { "Age", "27" } };
var user = mapper.Map<User, Dictionary<string, string>>(dict);
Ответ 3
Поскольку я только что наткнулся на этот вопрос, я хотел бы добавить этот ответ возможно в текущей версии AutoMapper (даже если исходный вопрос уже довольно старый):
public class MyConfig
{
public string Foo { get; set; }
public int Bar { get; set; }
}
var config = new MapperConfiguration(cfg => {});
var mapper = config.CreateMapper();
var source = new Dictionary<string, object>
{
["Foo"] = "Hello",
["Bar"] = 123
};
var obj = mapper.Map<MyConfig>(source);
obj.Foo == "Hello"; // true
Ответ 4
Намного проще. Просто сопоставьте свой объект с KeyValuePair. Пример:
CreateMap<KeyValuePair<Guid, string>, User>()
.ForMember(u => u.Id, src => src.MapFrom(x => x.Key))
.ForMember(u => u.Name, src => src.MapFrom(x => x.Value));
Ответ 5
Этот поток немного староват, но в настоящее время есть как это сделать на автомате без какой-либо конфигурации, как указано в официальной документации:
AutoMapper может отображать в/из динамических объектов без какой-либо явной конфигурации (...) Аналогично, вы можете отображать прямо из словаря в объекты, AutoMapper выровняет ключи с именами свойств.
Обновление:
Следующий код показывает рабочий образец (с юнит-тестами).
void Test()
{
var mapper = new MapperConfiguration(cfg => { }).CreateMapper();
var dictionary = new Dictionary<string, object>()
{
{ "Id", 1 },
{ "Description", "test" }
};
var product = mapper.Map<Product>(dictionary);
Assert.IsNotNull(product);
Assert.AreEqual(product.Id, 1);
Assert.AreEqual(product.Description, "test");
}
class Product
{
public int Id { get; set; }
public string Description { get; set; }
}