I have just started looking into using Autofac, and came across the Lifetime events OnActivating
and OnActivated
.
Now, I have read the Autofac documentation HERE
but it raises some questions on the difference between the two and their use.
Confusing points are:
The above docs say OnActivated
is raised "once a component is fully constructed". So, to me that implies for OnActivating
the component is NOT fully constructed, otherwise why bother mentioning it just for this event. If that is to be believed then how come you can change properties, and call methods on the instance (via the IActivatingEventArgs.Instance property) if it is not ready?
The docs say for OnActivating
that it is "raised before the component is used". Does "used" mean before any Resolve method passes the component out to client code?
Is the OnActivated
event also raised BEFORE the component is "used"? The docs say nothing on this, but choose to mention it for the OnActivating
event.
Would someone give a better account of when to use each event?
The OnActivated
event is fired when the whole component graph is fully build whereas the OnActivating
event is fired when the component is build.
Let suppose we have this graph
class Parent
{
public Parent(Child1 child1, Child2 child2, Child3 child3) { }
}
class Child1
{ }
class Child2
{
public Child2() { }
}
class Child3
{
public Child3(Child2 child2) { }
}
The event order will be :
Parent.preparing
Child1.preparing
Child1.activating
Child2.preparing
Child2.activating
Child3.preparing
Child2.preparing
Child2.activating
Child3.activating
Parent.activating
Child1.activated
Child2.activated
Child2.activated
Child3.activated
Parent.activated
Parent.release
Child3.release
Child2.release
Child2.release
Child1.release
Here is the code to trace these events :
public static class RegistrationExtensions
{
public static IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle>
Trace<TLimit, TActivatorData, TRegistrationStyle>(this IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> registration)
{
return registration.OnPreparing(e => { Console.WriteLine($"{e.Component.Activator.LimitType.Name}.preparing"); })
.OnActivating(e => { Console.WriteLine($"{e.Component.Activator.LimitType.Name}.activating"); })
.OnActivated(e => { Console.WriteLine($"{e.Component.Activator.LimitType.Name}.activated"); })
.OnRelease(e => { Console.WriteLine($"{e.GetType().Name}.release"); }); ;
}
}
The preparing
event is fired before the instance is being created. You can provide new parameter for the activation process.
The activating
event let's you change the instance with the ReplaceInstance
method. It is usefull if you want to mock or do any interception with the object.
The activated
event is really uncommon and you will almost never use it.
The release
event is fired when the associated lifetime scope is disposed
In your case if you want to call a method to initialize your object you should use the activating
event.