我想将已完成的国际象棋游戏存储在数据库中,以支持用户观看重播。
到目前为止,我有一个单例 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;
}
}
这显然会失败,因为无法注入(inject) EF Core
DbContext
进入这样的单例服务。我有一种模糊的感觉,我应该做这样的事情:
using (var scope = WhatDoIPutHere.CreateScope())
{
var DbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
DbContext.Replays.Add(new ReplayModel(...));
}
这是正确的方向吗?
最佳答案
你在正确的轨道上。 IServiceScopeFactory
可以做到这一点。
public class BattleManager : IBattleManager {
private readonly IServiceScopeFactory scopeFactory;
public BattleManager(IServiceScopeFactory scopeFactory)
{
this.scopeFactory = scopeFactory;
}
public void MyMethod() {
using(var scope = scopeFactory.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<DbContext>();
// when we exit the using block,
// the IServiceScope will dispose itself
// and dispose all of the services that it resolved.
}
}
}
DbContext
会表现得像它有一个 Transient
范围内using
陈述。
关于asp.net-core - 如何在单例服务中使用数据库上下文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51939451/