如何在 Autofac 的 OnActivated 处理程序中获取参数值?

How do I get the argument values within Autofac's OnActivated handler?

如果我有以下 classes:

public class A  {}
public class B { public B(A a) {…} }

然后我为 B 注册 OnActivated:

builder.RegisterType<B>().AsSelf().OnActivated(e => …)

如何获取作为 a 传递的实例而不需要 class B 公开它?

有多种方法可以实现您想要的效果。 @Hugo 已经评论过在激活器委托中进行解析,如下所示:

builder.RegisterType<B>().AsSelf().OnActivated(e =>
{
    e.Resolve<A>();
})

这当然意味着 A 需要注册一种比短暂 (​​InstancePerDependendency) 更长的生活方式。

第二种选择是在 B 上将 A 设为 public 属性。第三个选项是创建一个从 B 派生的 class 并包含 A 的 public 属性。此实现可以是组合根的一部分,这意味着您无需更改应用程序中的任何内容(组合根除外)。这是一个例子:

// Inside your Composition root
private sealed class C : B {
    public readonly A A;
    public C(A a) : base(a) { this.A = a }
}

builder.RegisterType<C>().As<B>().OnActivated(e => 
    e.Instance.A ...)

请注意,Autofac 或任何其他容器不可能以类型安全的方式为您提供 A,因为构造函数签名不是可以在通用类型约束中捕获的东西。所以 Autofac 能做的最好的事情就是为你提供一个带有注入类型的 List<object>。这是一个例子:

// Hypothetical feature
builder.RegisterType<C>().As<B>().OnActivated(e => {
    A a = e.Dependencies.OfType<A>().Single();
})

这里的问题是该列表应该具有哪些依赖项。如果类型被修饰或拦截,列表应该包含什么。该列表是否应包含 decorator/interceptor 的依赖项列表?或者它应该包含所有应用装饰器的所有依赖项和类型本身的依赖项,还是只包含该类型的依赖项。