我使用 Simple Injector 来创建 IoC 容器。我在这里采用了模式:
Page Navigation using MVVM in Store App
正如我在对上述帖子的评论中所问,我想注册 INavigationPage 的集合。我是这样做的:
private static void RegisterNavigationPages()
{
Container.RegisterCollection<INavigationPage>(new []
{
typeof(MainNavigationPage),
typeof(SecondNavigationPage)
});
}
在容器内我有 ViewModels 和 NavigationService 来:
Container.Register<INavigationService, NavigationService>(Lifestyle.Singleton);
Container.Register<IMainViewModel, MainViewModel>(Lifestyle.Singleton);
Container.Register<ISecondViewModel, SecondViewModel>(Lifestyle.Singleton);
这是我设置页面 DataContext 的方式:
DataContext = App.Container.GetInstance<IMainViewModel>();
一切正常,但我想在我的 ViewModel 构造函数中使用该集合中的 NavigationPages。我可以通过索引来完成:
public SecondViewModel(INavigationService navigationService, IEnumerable<INavigationPage> navigationPageCollection)
{
NavigationService = navigationService;
_navigationPage = (navigationPageCollection.ToList())[0];
GoToMainPageCommand = new Command(GoToMainPageAction);
}
但这不是优雅的解决方案,因为当我更改 NavigationPages 的顺序时,我将不得不更改整个应用程序中的所有索引。当我可以识别我想在 ViewModel 构造函数中使用哪个 NavigationPage 时,是否有任何解决方案?
我不能通过 typeof 来完成,因为 NavigationPage 类型在 UIProject 中,由于循环引用依赖,我无法从 ViewModel 项目中引用它。
请您参考如下方法:
目前 SecondViewModel 的正确性完全依赖于 navigationPageCollection 的顺序和填充,这使得它非常脆弱。如果您的 SecondViewModel 需要 MainNavigationPage,那么您应该注入(inject)它。不要注入(inject)集合;注入(inject)页面本身。这可能意味着 MainNavigationPage 需要自己的界面,例如 IMainNavigationPage。这消除了您现在的任何歧义。但是,与其拥有大量一对一映射的非通用接口(interface)(违反 RAP principle ),不如定义一个 few generic abstractions 可能更好。 .
