Caliburn.Micro导航导致StackOverflowException

问题描述

我正在尝试使用Caliburn.Micro及其SimpleContainer类在MVVM应用程序中设置导航。我需要将ShellViewModel注入Navigator才能访问ActivateItem()方法。首次加载外壳视图时,需要激活第一个子视图(CourseListViewModel)。为了执行此初始导航,我尝试将Navigator注入我的ShellViewModel中。问题在于这会导致StackOverflowException,因为ShellViewModel构造函数需要Navigator,而ShellViewModel则需要SimpleContainer,依此类推。

配置ShellViewModel后,我使用Singleton()方法注册了ShellViewModel。我的理解是,容器会在第一次请求时创建ShellViewModel的实例,然后为所有后续请求返回相同的实例,尽管我的ShellViewModel实际上并未实现单例模式。因此,我只希望class Bootstrapper : BootstrapperBase { public Bootstrapper() { Initialize(); } protected override void OnStartup(object sender,StartupEventArgs e) { DisplayRootViewFor<IShell>(); } private readonly SimpleContainer _container = new SimpleContainer(); protected override void Configure() { _container.Instance(_container); _container.Singleton<IEventAggregator,EventAggregator>() .Singleton<IWindowManager,WindowManager>() .Singleton<INavigator,Navigator>() // << Navigator is registered as a Singleton .Singleton<IShell,ShellViewModel>() // << ShellViewModel is registered as a Singleton .Singleton<Models.GoogleClassroom>(); // Register all ViewModels GetType().Assembly.GetTypes() .Where(type => type.IsClass) .Where(type => type.Name.EndsWith("ViewModel")) .Where(type => type.Name != "ShellViewModel") // Avoid registering ShellViewModel as a PerRequest instance .ToList() .ForEach(type => _container.RegisterPerRequest(type,null,type)); } protected override object GetInstance(Type service,string key) { return _container.GetInstance(service,key); } protected override IEnumerable<object> GetAllInstances(Type service) { return _container.GetAllInstances(service); } protected override void BuildUp(object instance) { _container.BuildUp(instance); } } 构造函数被调用一次,但这显然不是正在发生的事情。

引导程序

public class Navigator : INavigator
{
    private readonly IShell _shell;
    private readonly IWindowManager _windowManager;

    public Navigator(IShell shell,IWindowManager windowManager)
    {
        _shell = shell;
        _windowManager = windowManager;
    }

    // I can provide the rest of the methods if necessary but the exception occurs in the

}

导航器

public interface IShell : IConductActiveItem { }

public class ShellViewModel : Conductor<object>.Collection.OneActive,IHandle<object>,IShell
{

    private readonly IEventAggregator _eventAggregator;
    private readonly IWindowManager _windowManager;
    private readonly INavigator _navigator;

    public ShellViewModel(IWindowManager windowManager,IEventAggregator eventAggregator,INavigator navigator)
    {
        _windowManager = windowManager;
        _eventAggregator = eventAggregator;
        _eventAggregator.Subscribe(this);
        _navigator = navigator;

        // Activate the initial child view
        _navigator.To<CourseListViewModel>().Go();

    }
}

ShellViewModel

StackOverflowException

我单步执行该应用程序,发现protected override object GetInstance()是在IShell方法试图获取类型_container.Singleton()的实例时发生的,但是由于我相信{{1 }}注册成功了,我花了一些时间才弄清楚发生了什么。在尝试调试时,我从Navigator构造函数中删除了ShellViewModel,而是注入了导体本身。然后,我尝试如下激活初始子视图:

public ShellViewModel(IWindowManager windowManager,SimpleContainer container) // INavigator navigator)
{
    // Code shortened,but same as above
    
    // GetInstance<IShell>() calls this constructor recursively
    container.GetInstance<IShell>().ActivateItem(container.GetInstance<CourseListViewModel>());

}

您可以在评论中看到,这是我发现问题的地方。 ShellViewModel构造函数被递归调用,而不是导体像我期望的那样注入现有对象(Singleton)。

我的问题是我是否误解了SimpleContainer.Singleton()是做什么的还是使用不正确?以及实现此问题的正确方法是什么,以解决我的初始导航问题并仍然为其注入依赖项?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)