Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果父对象是单例对象,那么创建dbcontext(EF-core)的最佳实践是什么?_C#_Dependency Injection_Entity Framework Core_Botframework_Dbcontext - Fatal编程技术网

C# 如果父对象是单例对象,那么创建dbcontext(EF-core)的最佳实践是什么?

C# 如果父对象是单例对象,那么创建dbcontext(EF-core)的最佳实践是什么?,c#,dependency-injection,entity-framework-core,botframework,dbcontext,C#,Dependency Injection,Entity Framework Core,Botframework,Dbcontext,我用。我将使用实体框架核心来保存状态。我遇到了一个问题。IStorage接口以单例的形式注入,因为使用此接口的其他对象以单例的形式注入 services.AddSingleton<IStorage>(new MyDbStorage()); //<-- my storage with dbcontext services.AddSingleton<UserState>(); //This class has ctor

我用。我将使用实体框架核心来保存状态。我遇到了一个问题。IStorage接口以单例的形式注入,因为使用此接口的其他对象以单例的形式注入

        services.AddSingleton<IStorage>(new MyDbStorage()); //<-- my storage with dbcontext
        services.AddSingleton<UserState>();          //This class has ctor with IStorage param
        services.AddSingleton<ConversationState>();  //And this class has ctor with IStorage param
        services.AddSingleton(sp =>
        {
            var userState = sp.GetService<UserState>();
            var conversationState = sp.GetService<ConversationState>();
            return new BotStateSet(userState, conversationState);
        });
有关详细信息,请参见。 我知道。 您能为我推荐一些创建dbcontext的选项吗? 我考虑过DbContextFactory,但我不知道如何确切地创建它

更新
我已经更新了代码。请参阅第一行。

首先,请不要使用接口抽象MyDbContext,否则您将无法访问EF fetures或将尝试隐藏EntityFramework命名空间。使用扩展名。这样,DbContext将被注册为作用域,它的最佳生存期是什么

将IServiceProvider注入到singleton UserState和ConversationState中,然后仅在需要时创建作用域并解析此作用域内的MyDbContext实例

但是,如果UserState和ConversationState所做的工作应该作为单个事务执行,这意味着在同一个DbContext实例上,那么最好在BotStateSet中解析MyDbContext,并将其作为参数传递到UserState和ConversationState的方法中


我不熟悉Virtual Assistant,但如果可以对状态类(至少对UserState和ConversationState)使用瞬态生存期,它将允许您将MyDbContext注入构造函数,避免将其作为参数传递。

那么,为什么您不能简单地添加is as.AddTransient?其他人可能是单身,但这一个是暂时的。还是我遗漏了什么?@Fabjan,UserState是个单身汉。这意味着ctor将只执行一次。正如您所知,UserState-ctor具有param-IStorage。UserState对象将不会在下一个请求或其他任何请求中重新创建。这意味着历史就像一个瞬间,这并不重要。在本例中,瞬态与单例相同。好的,当再次读取代码时,他们使用的是CosmosDbStorage,而不是DbContext,所以没关系。但是整个代码看起来很难看,我问自己为什么?几乎在每一行代码上。不幸的是,我不能编辑这个集合。它位于Microsoft.Bot.Builder命名空间内。
public class UserState
{
    private readonly IServiceProvider _provider;

    public UserState(IServiceProvider provider)
    {
        _provider = provider;
    }

    public async Task DoWorkAsync()
    {
        using (var scope = _provider.CreateScope())
        using (var ctx = scope.ServiceProvider.GetService<MyDbContext>())
        {
            // do work
            await ctx.SaveChangesAsync();
        }
    }
}