Autofac:关于OnActivating和OnActivated的问题

Autofac : Questions about OnActivating and OnActivated

我刚刚开始研究使用 Autofac,并遇到了生命周期事件 OnActivatingOnActivated

现在,我已经阅读了 Autofac 文档 HERE

但它提出了一些关于两者之间的区别及其使用的问题。

混淆点是:

  1. 上面的文档说 OnActivated 被提升 "once a component is fully constructed"。所以,对我来说,这意味着 OnActivating 组件没有完全构建,否则为什么只为这个事件费心提到它。如果这是可信的,那么如果它还没有准备好,你怎么能改变属性,并在实例上调用方法(通过 IActivatingEventArgs.Instance 属性)?

  2. 文档说 OnActivating 是 "raised before the component is used"。 "used" 是否意味着在任何 Resolve 方法将组件传递给客户端代码之前?

  3. 在组件 "used" 之前是否也引发了 OnActivated 事件?文档对此没有任何说明,但选择在 OnActivating 事件中提及它。

有人可以更好地说明何时使用每个事件吗?

OnActivated 事件在整个组件图完全构建时触发,而 OnActivating 事件在组件构建时触发。

假设我们有这张图

class Parent
{
    public Parent(Child1 child1, Child2 child2, Child3 child3) { }
}
class Child1
{ }
class Child2
{
    public Child2() { }
}
class Child3
{
    public Child3(Child2 child2) { }
}

活动顺序为:

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

下面是跟踪这些事件的代码:

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"); }); ;
    }
}

preparing 事件在创建实例之前触发。您可以为激活过程提供新参数。 activating 事件允许您使用 ReplaceInstance 方法更改实例。如果您想模拟或对对象进行任何拦截,这将很有用。 activated 事件确实不常见,您几乎不会用到它。 release 事件在关联的生命周期范围被释放时触发

在你的情况下,如果你想调用一个方法来初始化你的对象,你应该使用 activating 事件。