Is there way to determine the point of time when all dependencies are already injected?

Apr 5, 2013 at 3:01 PM
I have several dependency properties in my class that were marked with the [Dependency] attributes.

I need to do additional initialization of my objects at point of time when all dependency properties were already set by Unity.

For example, I have:
[Dependency]
public IFirstApi FirstApi
{
    set;
    get;
}

[Dependency]
public ISecondApi SecondApi
{
    set;
    get;
}

protected virtual void Initialize()
{
    // Some code here that uses FirstApi and SecondApi
}
So, I need to call the Initialize method when the FirstApi and the SecondApi properties were already set by Unity, but I am not sure what is best way to do it.

For example in spring.net I can implement the IInitializingObject interface that defines the
void AfterPropertiesSet();
method that will be called by the spring.net after the dependency injection is complete.

Is there something like this in Unity?
Apr 6, 2013 at 1:08 AM
Unity can call methods as part of the dependency chain. Just add the Dependency attribute to the method definition, but it must be public. I believe the properties are injected first, then methods are called.

Out of interest, why aren't you using constructor injection, as this would remove this as an issue ?
Apr 6, 2013 at 8:18 AM
Hi rslaney,

Thank you very much for reply. I've checked the [InjectionMethod] attribute and it works excellent. You are right, the Unity initializes the properties marked with the [Dependency] first and then calls method marked with the [InjectionMethod] attribute.

Actually we use both (property injection and constructor injection techniques). I've asked about properties injection because it simpler example.

With constructor injection we also had similar problem. For example I have the BaseViewModel class, which has the Initialize template method:
public abstract class BaseViewModel : NotificationObject
{
    protected IEventAggregator EventAggregator
    {
        private set;
        get;
    }

    protected BaseViewModel(IEventAggregator eventAggregator)
    {
        EventAggregator = eventAggregator;
        Initialize();
    }


    protected virtual void Initialize()
    {
        CreateCommands();

        if (EventAggregator != null)
        {
            SubscribeToEvents();
        }

        SetupDefaultValues();
    }

    protected virtual void CreateCommands()
    {
    }

    protected virtual void SubscribeToEvents()
    {
    }

    protected virtual void SetupDefaultValues()
    {
    }

}
and have the CurrentUserViewModel derived class, which overrides the SetupDefaultValues method:
public class CurrentUserViewModel : BaseViewModel
{
    protected ISecurityApi SecurityApi
    {
        private set;
        get;
    }

    public string UserName
    {
        private set;
        get;
    }


    public CurrentUserViewModel (IEventAggregator eventAggregator, ISecurityApi securityApi)
        : base(eventAggregator)
    {
        SecurityApi = securityApi;
    }


    protected override void SetupDefaultValues()
    {
        UserName = SecurityApi.GetCurrentSession().UserName;
    }

}
The call sequence in this example during the CurrentUserViewModel object creation will be BaseViewModel.Constructor -> BaseViewModel.Initialize -> CurrentUserViewModel .SetupDefaultValues (since it overrides base) -> CurrentUserViewModel.Constructor

So, when we reach the CurrentUserViewModel.SetupDefaultValues the SecurityApi property still will not be initialized.

With your idea now I can redesign the base class as:
public abstract class BaseViewModel : NotificationObject
{
    protected IEventAggregator EventAggregator
    {
        private set;
        get;
    }

    protected BaseViewModel(IEventAggregator eventAggregator)
    {
        EventAggregator = eventAggregator;
    }

    [InjectionMethod]
    public virtual void AfterInjectionComplete
    {
        Initialize();
    }

    protected virtual void Initialize()
    {
        CreateCommands();

        if (EventAggregator != null)
        {
            SubscribeToEvents();
        }

        SetupDefaultValues();
    }

    protected virtual void CreateCommands()
    {
    }

    protected virtual void SubscribeToEvents()
    {
    }

    protected virtual void SetupDefaultValues()
    {
    }

}
Apr 9, 2013 at 10:55 PM
glad to know it's worked.

There is no easy solution for getting around requiring virtual method calls in constructors. It usually means a redesign.