我有三种类型的项目如下:
public class StockItem
{
public int Id { get; set; }
public string Name { get; set; }
public decimal UnitPrice { get; set; }
}
public class LotItem : StockItem
{
public virtual ICollection<Lot> Lots { get; set; }
}
public class DetailedItem : StockItem
{
public virtual ICollection<SerialNumber> SerialNumbers { get; set; }
}
当我开发一个使用MVVM,WPF,PRISM,EF5的应用程序时,我有点困惑:
第一:我如何使用一个根据类型更改(显示/隐藏控件)的视图对这些类型执行CRUD,知道我可能在以后继承相同类型的新类型?
第二:我如何将视图绑定到视图模型:
>我是否需要公开动态属性才能处理这三种类型?
> MVVM中是否有一个提示要克服这个问题?
最佳答案 另一种不破坏开放/封闭原则的方法是为每种类型的StockItem创建视图模型和视图,然后使用一种类型来整理所有公开的子类型及其相应的视图模型,并提供一种工厂方法获取StockItem并返回匹配的视图模型.
例如,使用IoC容器或MEF很容易做到这一点.
更新
作为使用MEF的简单示例:
public class StockItemEditViewModelFactory : IPartImportsSatisfiedNotification
{
private Dictionary<Type, IStockItemEditViewModelResolver> resolvers;
[ImportMany(IStockItemEditViewModelResolver)]
private IEnumerable<IStockItemEditViewModelResolver> importedResolvers;
public void OnImportsSatisfied()
{
// Build dictionary of StockItem -> StockItemEditViewModel
// Do error handling if no imported resolvers or duplicate types
resolvers = new Dictionary<Type, IStockItemEditViewModelResolver>
foreach(var importedResolver in importedResolvers)
{
resolvers.Add(importedResolver.StockItemType, importedResolver);
}
}
public IStockItemEditViewModel Create(StockItem stockItem)
{
// Find the appropriate resolver based on stockItem.GetType(), handle errors
var type = stockItem.GetType();
var entry = this.resolvers.FirstOrDefault(kv => kv.Key == type);
var resolver = entry.Value;
return resolver.CreateEditViewModel(stockItem);
}
}
[InheritedExport]
public interface IStockItemEditViewModelResolver
{
Type StockItemType { get; }
IStockItemEditViewModel CreateEditViewModel(StockItem stockItem);
}
public class LotItemEditViewModelResolver : IStockItemEditViewModelResolver
{
Type StockItemType { get { return typeof(LotItem); } }
IStockItemEditViewModel CreateEditViewModel(StockItem stockItem)
{
return new LotItemEditViewModel(stockItem);
}
}
public class MainViewModel
{
public IStockItemEditViewModel ActiveItem { get; private set; }
public MainViewModel(StockItemEditViewModelFactory editViewModelfactory)
{
StockItem stockItem = new LotItem();
this.ActiveItem = editViewModelFactory.Create(myStockItem);
}
}
这是未经测试的,但它向您展示了一般方法.您可以使用泛型来使这更整洁.
如果你想使用Unity而不是MEF,那么概念将是相同的,但你需要注册IStockItemEditViewModelResolver的每个实现(或使用Unity扩展并使用约定),然后你的工厂需要一个引用容器,以便它可以做一个ResolveAll(见Unity Resolve Multiple Classes).