Reputation: 81
All I have some experience with Caliburn.Micro using System.ComponentModel.Composition
as an IoC container. This time I want to have some fun and use Niject. To setup the Calburn.Micro bootstrapper, I have the following 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);
}
}
This seem to be called fine, but when the line
DisplayRootViewFor<IMainWindowViewModel>();
Is hit, it seems to launch the view IMainWindowView okay, but
public partial class MainWindowView : Window
{
public MainWindowView()
{
InitializeComponent();
}
}
public interface IMainWindowViewModel { }
and MainWindowViewModel
as
public class MainWindowViewModel : Conductor<IMainWindowViewModel>, IMainWindowViewModel { }
with the XAML of IMainWindowView
as
<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>
The ctor is called over and over again and results in a StackOverflow exception, there is no clear cause for this what-so-ever. This type is bound in singleton scope. Why is this happening am I missing something?
Upvotes: 1
Views: 120
Reputation: 35681
<Window.DataContext>
<ViewModels:MainWindowView/>
</Window.DataContext>
it doesn't make sense to set DataContext of MainWindowView to another instance of MainWindowView which will also try to set DataContext etc, until you get StackOverflow exception.
it should be a view model in DataContext. I don't know if caliburn.micro creates view models for view based on conventions, but at least remove current <Window.DataContext>
assignment.
it is not clear to me why view namespace is aliased as ViewModels. If real view model is in the same namespace and it is not resolved automatically, assign view model
<Window.DataContext>
<ViewModels:MainWindowViewModel/>
</Window.DataContext>
DI container really should provide constructor arguments.Use them to assign DataContext:
public MainWindowView(IMainWindowViewModel vm)
{
InitializeComponent();
DataContext = vm;
}
Upvotes: 2