Zenject - 与接口绑定时限制类的使用

问题描述 投票:0回答:1

使用 zenject 我有一个类,比如说 A。然后是另一个实现接口 IB 的类 B。我想将容器中B的接口(仅接口)绑定为单个,但在注入A时将整个类B绑定为单个。所以最后只有一个 B 实例。

所以我想允许类A使用B属性,但任何其他类不能注入B,它们只能注入接口(IB)。

是否可以在 InstallBindings 方法中不使用 Resolve 来实现(因为不推荐)?

c# unity-game-engine zenject
1个回答
0
投票

简单模式:

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>()

© www.soinside.com 2019 - 2024. All rights reserved.