我刚刚使用mvvmlight创建了我的第一个c#/ XAML应用程序,并且我尝试尽可能地实现MVVM模式(WP8应用程序)。但是,我已经慢慢地将我的代码转换为某种风格,我认为它没有正确实现该模式!关于事情应该如何的任何建议都会有很大的帮助。
例如,使用mvvmlight我正在大量使用ViewModelLocator。我的一些视图模型会立即创建,例如SettingsViewModel(有一个SettingsView)。
SimpleIoc.Default.Register<SettingsViewModel>(true);
然后在我的项目的其他地方,我的其他视图模型将通过属性或方法直接访问此视图模型以获取偶尔的信息......像这样;
mySetting = ViewModelLocator.SettingsStatic.GetSomeSetting(var);
我担心的是我的观点模型越来越多地以这种方式相互交谈。这个问题是它们现在可能无法独立测试,因为它们需要或假设存在其他视图模型。
这里的任何指针都会很棒!
编辑:另一个例子是拥有一个PersonView,PersonViewModel有一些帮助显示UI的方法。在某些情况下,我有其他视图需要显示此信息....我使用viewmodellocator来获取它们,而不是在当前视图模型中再次编写辅助方法。答案 0 :(得分:2)
你认为视图模型依赖于视图模型会导致麻烦,你是对的。当我需要访问我的应用程序中的“全局”设置时,我使用可以在视图模型的构造函数中注入的接口。因此,您可以创建包含所需属性和方法的ISettingsService。您还可以创建一个模拟或伪造ISettingsService接口的数据/属性的设计时设置服务
然后在您的视图模型定位器中使用:
if (ViewModelBase.IsInDesignModeStatic) {
SimpleIoc.Default.Register<ISettingsService, DesignSettingService>();
} else {
SimpleIoc.Default.Register<ISettingService, SettingService>();
}
创建实现ISettingsService的DesignSettingService和SettingService。
至于你的模型,SimpleIOC将解析/注入传递给类构造函数的必需元素。如果你有一个名为MyViewModel的类/视图模型,并且它想要使用settingsservice,那么你可以像这样定义构造函数:
private ISettingsService _SettingsAccess;
public New(ISettingsService SettingsService)
{
_SettingsAccess = SettingsService;
SettingProperty= _SettingsAccess.GetProperty;
}
这样可以在构造函数中解析此服务时保持视图模型的分离,这样就可以在不破坏使用它的每个视图模型的情况下更改ISettingsService的实现。
我使用INavigationService来处理我的应用程序中的所有导航事件,这允许我取消基于另一个viewmodels属性的导航,而不需要当前直接调用/引用其他viewmodel。
一个视图模型永远不应该直接调用另一个视图模型。使用此方法,您可以向viewmodel传递所需数量的“服务”。除了导航服务之外,我使用的每个viewmodel都会获得一个连接到我的模型的dataservice。 IE浏览器。处理人员的视图模型获取IPeopleDataService,其中此服务包含影响数据库的所有CRUD操作。这样我就可以更改数据库和服务功能中的人员对象,而不必更改人员视图模型。
我希望这会有所帮助。