如何从MVVM样式的模型接口创建视图模型?

时间:2015-06-17 14:51:05

标签: c# wpf mvvm model viewmodel

我正在使用视图模型第一种方法,在某些模型中,我通过这样的界面公开其他模型:

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?
    }

}

可能的解决方案

变式1:

存储IModelIViewModel转换器的集合,并在ViewModel中使用它们。

private IDictionary<type,Func<IModel,IViewModel>> converters;
private IViewModel ToViewModel(IModel model)
{
    return converters[model.GetType()](model);
}

优点:

  • 模型不必了解视图模型
  • 可以选择ViewModels

缺点:

  • 如果没有合适的转换器,该过程可能会在运行时失败

变式2:

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);
    }
}

优点:

  • 可以选择ViewModels
  • 易于使用,难以滥用

缺点:

  • 模型必须了解视图模型

我正在寻找没有缺点的变种。

1 个答案:

答案 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映射。