Search code examples
wpfdependency-injectionunity-containerprismeventaggregator

Use Unity Property Dependency Injection with EventAggregator


I have WPF Project with Prism 7.1, Unity DI 5.8.11 and .NET framework 4.7

I have BaseViewModel which all the ViewModel classes will inherit from

public abstract class BaseViewModel : BindableBase
{
    [Dependency]
    protected IEventAggregator EventAggregator { get; set; }

    // just default constructor, no other constructor is needed
}

and here is an example of one of the ViewModel class

public class TablesViewModel : BaseViewModel
{
    public TablesViewModel()
    {
        EventAggregator.GetEvent<OperatorChangedEvent>().Subscribe(.....);
    }
}

and the register of the type as the following

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    containerRegistry.RegisterInstance<IEventAggregator>(new EventAggregator());       
}

Now, what happened is the following: First the constructor of the BaseViewModel is called then the constructor of the TablesViewModel then the Dependency property is set by the Unity DI, this is a logical sequence of events, but it does not fit for me. the constructor of the TablesViewModel is giving a null reference Exception because the EventAggregator property is still null.

I do not want to use the constructor dependency injection, this will force me to create a lot of non-default constructor for all the ViewModel classes. and at the same time, I need to subscribe to the EventAggregator at the constructor ( because there is no other good place to do that if there is please told me).

How can I solve this


Solution

  • I do not want to use the constructor dependency injection, this will force me to create a lot of non-default constructor for all the ViewModel classes.

    You want non-default constructors for classes that have dependencies. That's what dependency injection is all about: the types tell the user through their constructor parameters what he has to give them to operate.

    There are plenty of ways to create view models with non-default constructors, e.g. Prism's ViewModelLocator or Unity's automatic factories. You do not want to resort to using the ServiceLocator unless it is absolutely necessary, but an evil person technically could do something like this:

    public abstract class BaseViewModel : BindableBase
    {
        protected IEventAggregator EventAggregator { get; } = ServiceLocator.Current.GetInstance<IEventAggregator>();
    }