简单的注入器-寄存器收集

本文关键字:寄存器 注入器 简单 | 更新日期: 2023-09-27 18:16:37

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

在Store App中使用MVVM进行页面导航

正如我在上面帖子的评论中所要求的,我想注册INavigationPage的集合。我是这样做的:

 private static void RegisterNavigationPages()
 {
        Container.RegisterCollection<INavigationPage>(new []
        {
            typeof(MainNavigationPage),
            typeof(SecondNavigationPage)
        });
 }

在容器中,我有ViewModels和NavigationService to:

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的顺序时,我将不得不改变整个应用程序中的所有索引。它是任何解决方案,当我可以识别哪个NavigationPage我想在ViewModel构造器中使用?

我不能通过typeof来做,因为NavigationPage类型在UIProject中我不能从ViewModel项目中引用因为循环引用依赖

简单的注入器-寄存器收集

目前SecondViewModel的正确性完全依赖于navigationPageCollection的顺序和填充,这使得它非常脆弱。如果你的SecondViewModel需要MainNavigationPage,那就是你应该注射的。不要注入集合;注入页面本身。这可能意味着MainNavigationPage需要自己的接口,比如IMainNavigationPage。这就消除了你现在的困惑。但是,与其拥有大量一对一映射的非泛型接口(违反RAP原则),不如定义一些泛型抽象。

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

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