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 (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...