Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NullReferenceException in Caliburn.Micro's DisplayRootViewFor method when trying to use EventAggregator

I'm trying to use Caliburn Micro's built-in EventAggregator in my WPF project, based on this documentation. But the documentation (as I almost always find it with Caliburn Micro) seems incomplete, i.e. the sample code doesn't contain all implementation requirements.

In particular, I wasn't using an IoC container in my project, and I'm sure I'm missing or misusing some part of its configuration, and that is causing the issue.

The problem:

  • I'm getting NullReferenceException in the DisplayRootViewFor method on startup.
  • I obviously know what a NullReferenceException is generally, but I'd like to know how to solve this issue specifically connected to Caliburn Micro's app bootstrapper configuration (and to help other users who could encounter the same problem while trying to do the same thing).

Notes:

  • Admittedly, it's unclear to me how the app bootstrapper works, as I always found Caliburn Micro's documentation very hard to follow (compared to MSDN), and I didn't use an IoC container before.
  • The NullReferenceException is connected to the GetInstance override method, as if I comment it out, I get the "No parameterless constructor defined for this object" exception.
  • I already tried the solution in this question, but it didn't seem to make any difference.

Could somebody explain to me why does Caliburn.Micro throw this exception, and how I'm supposed to inject the EventAggregator to my main viewmodel? (Because trying to pass it as a parameter in DisplayRootViewFor didn't seem to work.)


My app bootstrapper looks like the following – based on the combination of The Event Aggregator and the Simple IoC Container documentation pages:

public class AppBootstrapper : BootstrapperBase
{
    private readonly SimpleContainer _container =
        new SimpleContainer();

    public AppBootstrapper()
    {
        Initialize();
    }

    protected override void Configure()
    {
        _container.Singleton<IEventAggregator, EventAggregator>();
    }

    protected override object GetInstance(Type serviceType, string key)
    {
        return _container.GetInstance(serviceType, key);
    }

    protected override IEnumerable<object> GetAllInstances(Type serviceType)
    {
        return _container.GetAllInstances(serviceType);
    }

    protected override void BuildUp(object instance)
    {
        _container.BuildUp(instance);
    }

    protected override void OnStartup(object sender, StartupEventArgs e)
    {
        DisplayRootViewFor<MainViewModel>();
    } 
}

And my MainViewModel's constructor looks like the following – set up for injecting the EventAggregator:

public MainViewModel(IEventAggregator eventAggregator)
{
    _eventAggregator = eventAggregator;
}
like image 935
Leaky Avatar asked Dec 23 '22 19:12

Leaky


1 Answers

Use the RegisterPerRequest to register the view model type itself. Try this:

public class HelloBootstrapper : BootstrapperBase
{
    private readonly SimpleContainer _container = new SimpleContainer();
    public HelloBootstrapper()
    {
        Initialize();
    }

    protected override void OnStartup(object sender, StartupEventArgs e)
    {
        base.OnStartup(sender, e);
        DisplayRootViewFor<MainViewModel>();
    }

    protected override void Configure()
    {
        _container.Singleton<IWindowManager, WindowManager>();
        _container.Singleton<IEventAggregator, EventAggregator>();
        _container.RegisterPerRequest(typeof(MainViewModel), null, typeof(MainViewModel));
    }

    protected override object GetInstance(Type serviceType, string key)
    {
        return _container.GetInstance(serviceType, key);
    }

    protected override IEnumerable<object> GetAllInstances(Type serviceType)
    {
        return _container.GetAllInstances(serviceType);
    }

    protected override void BuildUp(object instance)
    {
        _container.BuildUp(instance);
    }
}
like image 138
mm8 Avatar answered Dec 28 '22 05:12

mm8