如果我有以下课程:
public class A {}
public class B { public B(A a) {…} }
我为OnActivated
注册了B
:
builder.RegisterType<B>().AsSelf().OnActivated(e => …)
如何在不要求a
类公开的情况下获取作为B
传递的实例?
答案 0 :(得分:1)
有几种方法可以达到你想要的效果。 @Hugo已经评论过在激活器委托中执行解决方案,如下所示:
builder.RegisterType<B>().AsSelf().OnActivated(e =>
{
e.Resolve<A>();
})
这当然意味着A
需要注册的时间长于暂时(InstancePerDependendency
)。
第二个选项是在A
上将B
设为公共财产。第三种选择是创建一个派生自B
的类,并包含A
的公共属性。此实现可以是组合根的一部分,这意味着您不必更改应用程序中的任何内容(组合根除外)。这是一个例子:
// 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();
})
这里的问题是列表应该具有哪些依赖项。如果类型被装饰或截获,列表应包含什么。列表是否应包含装饰器/拦截器的依赖项列表?或者它应该包含所有应用装饰器的所有依赖关系以及类型本身的依赖关系,还是仅包含该类型的依赖关系。