首页 > 解决方案 > Autofac : 关于 OnActivating 和 OnActivated 的问题

问题描述

我刚刚开始研究使用 Autofac,并遇到了 Lifetime 事件OnActivatingOnActivated.

现在,我在这里阅读了 Autofac文档

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

令人困惑的地方是:

  1. 上面的文档说OnActivated“一旦组件完全构建”就会被提出。所以,对我来说,这意味着OnActivating组件没有完全构建,否则为什么要仅仅为了这个事件而提及它。如果这是可信的,那么如果它没有准备好,你怎么能改变属性,并调用实例上的方法(通过 IActivatingEventArgs.Instance 属性)?

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

  3. OnActivated在“使用”组件之前是否也引发了事件?文档对此只字未提,但选择在OnActivating活动中提及它。

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

标签: c#inversion-of-controlautofac

解决方案


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


推荐阅读