【发布时间】:2018-08-21 08:31:14
【问题描述】:
我想将完成的棋局存储在数据库中,以支持用户观看回放。
到目前为止,我有一个单例 GameManager 存储所有正在进行的游戏。所以在startup.cs 内我有以下代码行:
services.AddSingleton<IBattleManager, BattleManager>();
现在我想让BattleManager 访问DbContext 来保存已完成的游戏。
public class BattleManager : IBattleManager
{
//...
private void EndGame(ulong gameId)
{
var DbContext = WhatDoIPutHere?
lock(gameDictionary[gameId])
{
DbContext.Replays.Add(new ReplayModel(gameDictionary[gameId]));
gameDictionary.Remove(gameId)
}
}
}
是否有可能实现这一目标?怎么样?
尝试失败:
public class BattleManager : IBattleManager
{
Data.ApplicationDbContext _context;
public BattleManager(Data.ApplicationDbContext context)
{
_context = context;
}
}
这显然会失败,因为无法将 EF Core DbContext 注入到这样的 Singleton 服务中。
我有一种模糊的感觉,我应该做这样的事情:
using (var scope = WhatDoIPutHere.CreateScope())
{
var DbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
DbContext.Replays.Add(new ReplayModel(...));
}
这是正确的方向吗?
【问题讨论】:
-
通常情况下,DbContext 被注册为 Scope。为什么要注册为单身人士?
-
@Win 我知道 DbContext 已注册为 Scope。我不想将其注册为单例。但是,我需要一个 Singleton (GameManager) 将内容写入数据库。有可能吗?我的想法是,我需要以某种方式在 GameManager 的方法中创建范围,以便 DbContext 可以安全地驻留在那里而不会违反其范围。
-
或者Singletons永远不能访问数据库,句号,句号,因为我们可能不会,不应该以任何方式在Singletons中使用Scoped服务?
-
也许你应该问问自己为什么你认为你需要一个单身人士
IBattleManager。你从中得到什么?为什么它的多个实例不能存在?如果你把它做成 Scope 会破坏什么吗? -
@Brad 1) BattleManager 需要记住当前正在处理的回合之前的所有回合。我想既然它需要持续记住所有正在进行的游戏,它应该是一个单例。 2) 战斗管理器不是由 razor pages 调用,而是由 SignalR Hub 调用。
标签: asp.net-core singleton entity-framework-core