使用 zenject 我有一个类,比如说 A。然后是另一个实现接口 IB 的类 B。我想将容器中B的接口(仅接口)绑定为单个,但在注入A时将整个类B绑定为单个。所以最后只有一个 B 实例。
所以我想允许类A使用B属性,但任何其他类不能注入B,它们只能注入接口(IB)。
是否可以在 InstallBindings 方法中不使用 Resolve 来实现(因为不推荐)?
简单模式:
public override void InstallBindings() {
var b = new B();
Container.Bind<B>().FromInstance(b).AsTransient().WhenInjectedInto<A>();
Container.Bind<IB>().FromInstance(b).AsSingle();
Container.Bind<A>().AsSingle().NonLazy();
}
请注意,这里您指定什么范围并不重要(尽管 Zenject 不允许您使用两个
AsSingle
),无论如何它始终是同一个实例。我认为其余的都是不言自明的。
困难模式:
public override void InstallBindings() {
Container.Bind<IB>().To<B>().AsSingle();
Container
.Bind<B>()
.FromResolveGetter<IB>(_ => (B)Container.Resolve<IB>())
.WhenInjectedInto<A>();
Container.Bind<A>().AsTransient().NonLazy();
}
Zenject 提供了在
Container.Resolve
中直接使用 InstallBindings
的安全替代方案:
FromResolve
,这里没有多大用处,因为它只能解析绑定类型,FromResolveGetter
,这使我们能够自己解决绑定问题,包括以安全的方式使用 Container.Resolve
。这里相对简单:
IB
,已经绑定到B
的类型,被解析,然后转换为其具体类型。但仍要小心类型。您为 FromResolveGetter
指定的类型应该与您在 Container.Resolve
中使用的类型相同,而它返回的类型应该是您想要的类型。这里很容易误用类型,Zenject 会向您发送堆栈溢出或循环依赖错误消息,这对解释问题出在哪里没有太大帮助。
生成的绑定的使用仅限于
A
的类 WhenInjectedInto<A>()
。
另请注意,此绑定不需要范围,因为
B
已经受到前一个绑定的限制。
顺便说一句,接口也是如此。但根据接口的关联方式,转换可能会变得有些疯狂,例如
(IB2)(B)Container.Resolve<IB>()
。