如何在单例服务中使用数据库上下文? [英] How to use a database context in a singleton service?

查看:103
本文介绍了如何在单例服务中使用数据库上下文?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将完成的国际象棋游戏存储在数据库中,以支持用户观看重播.

I would like to store completed chess games in the database to support users watching replays.

到目前为止,我有一个单例GameManager,用于存储所有正在进行的游戏.因此,在startup.cs中,我有以下代码行:

So far I have a singleton GameManager that stores all ongoing games. So within startup.cs I have the following line of code:

services.AddSingleton<IBattleManager, BattleManager>();

现在,我想让BattleManager访问DbContext来保存完成的游戏.

Now I would like to have BattleManager access the DbContext to save completed games.

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

是否有可能实现这一目标?怎么样?

Is it possible to anyhow achieve this? How?

尝试失败:

public class BattleManager : IBattleManager
{
    Data.ApplicationDbContext _context;
    public BattleManager(Data.ApplicationDbContext context)
    {
        _context = context;
    }
}

这显然将失败,因为无法像这样将EF Core DbContext注入到Singleton服务中.

This will clearly fail since one cannot inject EF Core DbContext into a Singleton service like that.

我有一种模糊的感觉,我应该做这种事情:

I have a vague feeling that I should do something of this kind:

using (var scope = WhatDoIPutHere.CreateScope())
{
    var DbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
    DbContext.Replays.Add(new ReplayModel(...));
}

这是正确的方向吗?

推荐答案

您处在正确的轨道上. IServiceScopeFactory 可以做到.

You're on the right track. The IServiceScopeFactory can do that.

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的行为就像在该using语句中具有Transient范围一样.

The DbContext will behave like it has a Transient scope within that using statement.

这篇关于如何在单例服务中使用数据库上下文?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆