问题描述
我正在尝试使用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 (将#修改为@)