Я создаю приложение ASP.NET MVC 2 на C#, и я успешно использую Automapper для сопоставления значений между ViewModels и бизнес-объектами.Использование Automappper для сопоставления методам
В дополнение к нескольким явным свойствам, мои бизнес-объекты завершают словарь как catch для свойств, которые явно не определены. Нечто похожее на:
public class MyBusinessObject {
public void SetExtraPropertyValue<T>(string key, T value) {
// ...
}
public T GetExtraPropertyValue<T>(string key, T defaultValue) {
// ...
}
}
В моей ViewModel, у меня есть свобода, чтобы создать какие-либо свойства, которые я хочу, но я не могу изменить бизнес-объекты.
Так скажем, создать модель представления, как это:
class MyViewModel {
public string CustomProp { get; set; }
}
и значение, я хочу, чтобы хранить и извлекать нужно будет использовать
businessModelInstance.SetExtraPropertyValue("CustomProp", newVal);
и
businessModelInstance.GetExtraPropertyValue("CustomProp");
У меня проблемы с обоими направлениями.
Во-первых, при переходе от MyBusinessObject к MyViewModel, я подумал, что это должно быть просто сделать в моем пользовательском профиле Automapper:
CreateMap<MyBusinessObject, MyViewModel>()
.ForMember(dest => dest.CustomProp,
opt => opt.MapFrom(s => s.GetExtraPropertyValue("CustomProp", "")));
Однако MyBusinessObject.CustomProp
никогда не заселена, хотя и другие свойства.
Во-вторых, я не знаю, как настроить получение значения от MyViewModel.CustomProp
до звонка MyBusinessObject.SetExtraPropertyValue
.
- Есть ли способ сделать это сопоставление с Automapper?
- Есть ли совершенно другая атака, которую I следует попробовать?
- Должен ли я прибегать к ручному сопоставлению в моем контроллере? Например,
MyBusinessObject.SetExtraPropertyValue("CustomProp", MyViewModel.CustomProp)
UPDATE: Вот мое решение на основе предложений @Patrick Стила: Я добавил пользовательский атрибут к свойствам вида модели, что я хотел, чтобы отобразить дополнительные ключи собственности. Пользовательский TypeConverter использует отражение, чтобы найти эти атрибуты и свойства карты соответствующим образом.
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; }
}
В методе настроить пользовательский профиль класса:
CreateMap<MyViewModel, MyBusinessObject>()
.ConvertUsing<ItemExtraPropertyConverter>();
спасибо, что нашли время, чтобы посмотреть на него. вы правы, простой тест работал на меня. должно быть чем-то глупо в моем коде - это то, что я могу отлаживать. Для меня большая проблема заключается в том, как перейти в другое направление - сопоставление свойств модели представления с соответствующей записью словаря на бизнес-объекте.Я до сих пор не смог найти решение ... Есть идеи? – jaminto 2010-12-07 02:49:54