一般来说,我尽量避免使用全球服务定位器。我认为这是一种反模式。不要在viewModels中使用它。它会使测试成为一个熊。只需在构造函数中传递依赖关系即可。每个应用程序都有一个主IoC容器:我的主引导程序。然后我在一些工厂注册的人少得多。我从不暴露容器。这个计划是在多年的战斗中失踪和过时的依赖。
viewModel级别应该使用PropertyChanged和ObservableCollection的东西来暴露它的事件。如果你能够帮助,没有人应该以编程方式注册这些人;它们应该全部用于UI级别的绑定。硬件抽象只是模型级实体的另一种形式。它是(数据的来源)。您可以有多个数据/模型图层。
在(viewModel或模型管理器)构造函数中注册模型级事件是正确的。在Dispose中清理它们。我已经做了一件事,使其更清洁一点就是在有人注册时在模型中触发事件。它看起来像这样:
class ModelManager: IModelManager {
...
private Action<IModel> _modelAdded = delegate {};
public event Action<IModel> ModelAdded {
add {
_modelAdded = Delegate.Combine(_modelAdded, value);
foreach(var model in Models)
value.Invoke(model);
}
remove { ... }
}
...
}
class ModelManagerVM: ViewModelBase {
public ModelManagerVM(IModelManager mgr, IModelVMFactory factory) {
_factory = factory;
_mgr = mgr;
_mgr.ModelAdded += OnModelAdded; // triggers on subscribe
}
private void OnModelAdded(IModel model) { // never virtual
// use a dispatcher to push this to the UI thread
var existing = _modelVMs.FirstOrDefault(m => m.ID == model.ID);
if (existing != null) existing.Model = model;
else _modelVMs.Add(_factory.Create(model));
}
public void Dispose() {
_mgr.ModelAdded -= OnModelAdded; // always unsubscribe on passed-in deps
}
}