我无法将标准接口 Zenject ITickable 绑定到 AsTransient() 类。 Tick() 未调用

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

我有一个

Timer
类,它实现了标准 Zenject
ITickable
接口:

Timer: ITickable {
    public void Tick() {}
}

我想为每个需要它的类创建一个新的

Timer
实例。

我这样做(我想将

ITickable
绑定到
Timer
):

Container.BindInterfacesAndSelfTo<Timer>().AsTransient();

我获得了依赖性,但方法

Tick()
未被调用。

如果我将注册更改为 AsSingle:

Container.BindInterfacesAndSelfTo<Timer>().AsSingle();

方法

Tick()
被正常调用。

如何使用

Timer
AsTransient() 获取
ITickable
的新实例?

unity-game-engine dependency-injection zenject
1个回答
0
投票

TickableManager
是负责IxTickable接口的管理器。 它通过注入获取实例列表。因此,当 Zenject Binder 在类中注入依赖项时,它会查找实现方法的特定提供程序以获取确切的对象。因此,当您使用 .AsTransient 时,它会调用瞬态提供程序。它的指令是当有人请求时返回一个新实例。因此,由于
TickableManager._tickables
也是注入的
List<ITickables>
,因此瞬态提供程序为此列表创建的实例也是全新的。

所以你这里有 3 个选择:

  1. 您可以在 TickableManager 中强制添加 Timer 实例。
Container.Bind<Timer>().AsTransient().OnInstantiated<Timer

   >((_context,_object)=> _context.Container.Resolve<TickableManager>().Add(_object));
  1. 您可以为定时器绑定不同的id。但这仅在极少数情况下才合理。一般来说,这是一种不好的做法。
   Container.Bind(typeof(ITickable),typeof(Timer)).WithId(1).To<Timer>().AsSingle();
   Container.Bind(typeof(ITickable),typeof(Timer)).WithId(2).To<Timer>().AsSingle();
  1. 您可以对每个对象使用
    GameObjectContext
    。如果您尝试创建某种游戏实体集合:敌人、武器、NPC 等,那么这种方法是最好的。您只需将
    GameObjectContext
    添加到实体预制件的根目录即可。然后为此上下文创建安装程序,其中应该绑定 Timer .AsSingle.

这真是一个棘手的问题。花了好几个小时才找到解决方案。我已经后悔回答这个问题了。

附注不要害怕在 IDE 中按 F12 和 Ctrl+F12 在外部库中查找某些内容。通过这样做你可以获得重要的经验。

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