我正在使用视图模型第一种方法,在某些模型中,我通过这样的界面公开其他模型:
public class ModelA : IModel {}
public class ModelB : IModel {}
// plus yet unknown additional models
public class ViewModelA : IViewModel
{
ViewModelA(ModelA model){}
}
// a model may have several possible view models that should be selectable somehow
public class ViewModelAVariant : IViewModel
{
ViewModelAVariant(ModelA model){}
}
public class ViewModelB : IViewModel {}
{
ViewModelA(ModelB model){}
}
public class ModelContainer
{
public IModel[] SubModels { get { return new IModel { new ModelA(), new ModelB()};}}
}
public class ViewModelContainer
{
private ModelContainer modelContainer;
public IViewModel[] SubModels
{
get
{
return modelContainer.SubModels.Select( sm => ToViewModel(sm)).ToArray();
}
}
private IViewModel ToViewModel(IModel model)
{
// what to insert here?
}
}
存储IModel
到IViewModel
转换器的集合,并在ViewModel中使用它们。
private IDictionary<type,Func<IModel,IViewModel>> converters;
private IViewModel ToViewModel(IModel model)
{
return converters[model.GetType()](model);
}
优点:
缺点:
interface IModel
{
IViewModel ToViewModel();
}
public class ModelA : IModel
{
// this enables view model selection
public ModelA(Func<ModelA,IViewModel> converter)
{
this.converter = converter;
}
private Func<ModelA,IViewModel> converter;
public IViewModel ToViewModel()
{
return converter(this);
}
}
优点:
缺点:
我正在寻找没有缺点的变种。
答案 0 :(得分:0)
听起来像是AutoMapper的一个很好的用例。
基本上你会创建一个配置,在最简单的情况下它是:
Mapper.CreateMap<ModelA, ViewModelA>();
Mapper.CreateMap<ModelA, ViewModelAVariant<>();
Mapper.CreateMap<ModelB, ViewModelB>();
这假设所有属性都命名相同(在ViewModel和Model中)。它还可以展平属性,即ModelA.Property
按惯例映射到ModelAProperty
(如果存在)。
如果您有更复杂的映射,则必须配置映射。
然后通过
解决它ModelA modelA = ... // retrieve ModelA
ViewModelA viewModelA = Mapper.Map<ViewModelA>(modelA);
和变化:
ModelA modelA = ... // retrieve ModelA
ViewModelAVariation viewModelA = Mapper.Map<ModelA, ViewModelAVariation>(modelA);
您不应该以其他方式使用它,至少不建议将ViewModel转换为域/业务模型。它的主要目标是模型到DTO(数据传输对象)或模型到ViewModel映射。