Simple Injector - 寄存器集合

Simple Injector - register collection

我使用 Simple Injector 创建 IoC 容器。我在这里拿了模式:

Page Navigation using MVVM in Store App

正如我在上面 post 的评论中所问,我想注册 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,那就是您应该注入的。不要注入集合;注入页面本身。这可能意味着 MainNavigationPage 需要自己的接口,例如 IMainNavigationPage。这消除了您现在的任何歧义。但是没有负载一对一映射非通用接口(违反 RAP principle), you might be better of defining a .

我也有类似的问题,之前解决过这个问题。在这里阅读我的博客 clean factory pattern

基本上您需要的是添加一个方法或属性 来在INavigationPage 中识别用户,然后在SecondViewModel 中也添加相同的标识符。 SecondViewModel 构造函数只需要遍历 IEnumerable 并找到它需要的页面。