di.dart 中的单例

Singleton in di.dart

如何在 di.dart 中创建单例实例?

好像我这样做:

module = new Module()
  ..bind(GameRepository)
  ..bind(MessageFactory)
  ..bind(Broadcaster);

如果我

我的 GameRepository 会被多次实例化

injector.get(GameRepository)

我试过了

..bind(GameRepository, toValue: new GameRepository())

这似乎可行,但它很容易,因为 GameRepository 没有参数,但不应该有一种方法告诉 di 框架将其绑定为单例而不需要我实例化它(并维护其构造函数调用?)

编辑: @Günter,我确实想要一个单身人士,但在我的情况下,我想使用我的 redstone.dart 资源中的 GameRepository 以及外部资源。所以我绑定 GameRepository 然后这样做:

// To use it outside of the resource
injector = new ModuleInjector([modules.getProductionModule()]);
// To use it in redstone
app.addModule(module);

现在我可以看到红石在 GameRepository 上的引用与我在 injector.get(GameRepository)

上得到的引用不同

我不知道这个问题是否变得太具体了:P

据我所知 DI 总是 returns 同一个实例,因此一切都是单例。如果你不想要单身人士,你可以绑定一个工厂。 有关详细信息,请参阅

在 class

的实现或扩展中使用具有单例模式的工厂构造函数怎么样?
class GameRepositorySingleton extends GameRepository{

    static GameRepository _instance;

    factory GameRepositorySingleton (A a, B b, ...){
        if (_instance == null)
        {
            _instance = new GameRepository (a, b);
        }
        return _instance;
    }
}

然后你就可以像这样在 DI 中使用它了

module = new Module()
  ..bind(GameRepository, toImplementation: GameRepositorySingleton);

老实说我还没有试过这个。告诉我它是否有效。如果编辑抱怨 GameRepository 不是 GameRepositorySingleton

,您可能必须将 extends 更改为 implements

所以我暂时就这样做了。因为我现在需要红石之外的 DI,所以我在顶层有一个注入器。理想情况下,我可以与 Redstone 共享注入器,但据我所知这似乎是不可能的。我已经打开了一个问题 here。所以现在,我认为在红石和我的代码之间共享单例实例的最佳方式是遵循这些思路。

// in my top-level main()
ModuleInjector injector = new ModuleInjector([new Module()..bind(GameRepository)]);

// setup of redstone
GameRepository repo = injector.get(GameRepository);
app.addModule(new Module()..bind(GameRepository, toValue: repo));

// in my redstone resource
@app.Group('/games')
class GamesResource {
  GameRepository gameRepository;

  Games(this.gameRepository);
}