一般來說,我儘量避免使用全球服務定位器。我認爲這是一種反模式。不要在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
}
}