在 WPF 中使用 Ninject 作为带有 Calburn.Micro 和 MVVM 的 DI 容器
Using Ninject as the DI Container with Calburn.Micro and MVVM in WPF
我对 Caliburn.Micro 使用 System.ComponentModel.Composition
作为 IoC 容器有一些经验。这次我想找点乐子,使用 Niject。要设置 Calburn.Micro 引导程序,我有以下 class
public class Bootstrapper : BootstrapperBase
{
private IKernel _kernel;
public Bootstrapper()
{
Initialize();
}
protected override void Configure()
{
_kernel = new StandardKernel();
_kernel.Bind<IWindowManager>().To<WindowManager>().InSingletonScope();
_kernel.Bind<IEventAggregator>().To<EventAggregator>().InSingletonScope();
_kernel.Bind<IMainWindowViewModel>().To<MainWindowViewModel>().InSingletonScope();
}
protected override object GetInstance(Type service, string key)
{
return _kernel.Get(service);
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return _kernel.GetAll(service);
}
protected override void OnStartup(object sender, StartupEventArgs suea)
{
base.OnStartup(sender, suea);
DisplayRootViewFor<IMainWindowViewModel>();
}
protected override void OnExit(object sender, EventArgs e)
{
_kernel.Dispose();
base.OnExit(sender, e);
}
}
这个好像还可以,但是当行
DisplayRootViewFor<IMainWindowViewModel>();
被击中,好像启动视图IMainWindowView没问题,但是
public partial class MainWindowView : Window
{
public MainWindowView()
{
InitializeComponent();
}
}
public interface IMainWindowViewModel { }
和 MainWindowViewModel
作为
public class MainWindowViewModel : Conductor<IMainWindowViewModel>, IMainWindowViewModel { }
和IMainWindowView
的XAML为
<Window x:Class="Mole.Replay.Framework.MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ViewModels="clr-namespace:Mole.Replay.Framework"
xmlns:local="clr-namespace:Mole.Replay.Framework"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Window.DataContext>
<ViewModels:MainWindowView/>
</Window.DataContext>
<Grid>
</Grid>
</Window>
ctor 被一遍又一遍地调用并导致 Whosebug 异常,没有明确的原因导致这种情况。此类型绑定在单例范围内。为什么会发生这种情况是我遗漏了什么吗?
<Window.DataContext>
<ViewModels:MainWindowView/>
</Window.DataContext>
将 MainWindowView 的 DataContext 设置为 MainWindowView 的另一个实例是没有意义的,它也会尝试设置 DataContext 等,直到出现 Whosebug 异常。
应该是DataContext中的视图模型。我不知道 caliburn.micro 是否根据约定为视图创建视图模型,但至少删除当前的 <Window.DataContext>
分配。
我不清楚为什么视图命名空间别名为 ViewModel。如果真实视图模型在同一个命名空间中并且没有自动解析,则分配视图模型
<Window.DataContext>
<ViewModels:MainWindowViewModel/>
</Window.DataContext>
DI 容器确实应该提供构造函数 arguments.Use 它们来分配 DataContext:
public MainWindowView(IMainWindowViewModel vm)
{
InitializeComponent();
DataContext = vm;
}
我对 Caliburn.Micro 使用 System.ComponentModel.Composition
作为 IoC 容器有一些经验。这次我想找点乐子,使用 Niject。要设置 Calburn.Micro 引导程序,我有以下 class
public class Bootstrapper : BootstrapperBase
{
private IKernel _kernel;
public Bootstrapper()
{
Initialize();
}
protected override void Configure()
{
_kernel = new StandardKernel();
_kernel.Bind<IWindowManager>().To<WindowManager>().InSingletonScope();
_kernel.Bind<IEventAggregator>().To<EventAggregator>().InSingletonScope();
_kernel.Bind<IMainWindowViewModel>().To<MainWindowViewModel>().InSingletonScope();
}
protected override object GetInstance(Type service, string key)
{
return _kernel.Get(service);
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return _kernel.GetAll(service);
}
protected override void OnStartup(object sender, StartupEventArgs suea)
{
base.OnStartup(sender, suea);
DisplayRootViewFor<IMainWindowViewModel>();
}
protected override void OnExit(object sender, EventArgs e)
{
_kernel.Dispose();
base.OnExit(sender, e);
}
}
这个好像还可以,但是当行
DisplayRootViewFor<IMainWindowViewModel>();
被击中,好像启动视图IMainWindowView没问题,但是
public partial class MainWindowView : Window
{
public MainWindowView()
{
InitializeComponent();
}
}
public interface IMainWindowViewModel { }
和 MainWindowViewModel
作为
public class MainWindowViewModel : Conductor<IMainWindowViewModel>, IMainWindowViewModel { }
和IMainWindowView
的XAML为
<Window x:Class="Mole.Replay.Framework.MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ViewModels="clr-namespace:Mole.Replay.Framework"
xmlns:local="clr-namespace:Mole.Replay.Framework"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Window.DataContext>
<ViewModels:MainWindowView/>
</Window.DataContext>
<Grid>
</Grid>
</Window>
ctor 被一遍又一遍地调用并导致 Whosebug 异常,没有明确的原因导致这种情况。此类型绑定在单例范围内。为什么会发生这种情况是我遗漏了什么吗?
<Window.DataContext>
<ViewModels:MainWindowView/>
</Window.DataContext>
将 MainWindowView 的 DataContext 设置为 MainWindowView 的另一个实例是没有意义的,它也会尝试设置 DataContext 等,直到出现 Whosebug 异常。
应该是DataContext中的视图模型。我不知道 caliburn.micro 是否根据约定为视图创建视图模型,但至少删除当前的 <Window.DataContext>
分配。
我不清楚为什么视图命名空间别名为 ViewModel。如果真实视图模型在同一个命名空间中并且没有自动解析,则分配视图模型
<Window.DataContext>
<ViewModels:MainWindowViewModel/>
</Window.DataContext>
DI 容器确实应该提供构造函数 arguments.Use 它们来分配 DataContext:
public MainWindowView(IMainWindowViewModel vm)
{
InitializeComponent();
DataContext = vm;
}