Autofac:有关OnActivating和OnActivated

时间:2019-06-04 05:03:43

标签: c# inversion-of-control autofac

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

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

但是它对两者的区别及其用法提出了一些疑问。

令人困惑的点是:

  1. 上面的文档说OnActivated是在“组件完全构建后”提出的。因此,对我来说,这意味着OnActivating的组件尚未完全构建,否则为什么只为该事件而提到它。如果可以相信,那么如何更改属性,如果尚未准备好,可以通过实例调用方法(通过IActivatingEventArgs.Instance属性)?

  2. 文档针对OnActivating说,它是“在使用组件之前引发的”。 “已使用”是否意味着在任何Resolve方法将组件传递给客户端代码之前?

  3. 在组件“已使用”之前,OnActivated事件是否也会引发?文档对此一无所获,但选择在OnActivating事件中提及它。

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

1 个答案:

答案 0 :(得分:2)

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

假设我们有这张图

enter image description here

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事件。