c# - 通过 SignalR Core 访问数据库上下文
问题描述
我正在使用 AspNetCore.SignalR,我需要有关如何通过 Hub 访问我的 SQL Server 数据库的建议。关于这方面的资源并不多。我知道如何添加一个单例,但我不知道以后如何访问它。如何访问在集线器任务内的 Startup.cs 中使用 Configuration.GetConnectionString 定义的数据库上下文?
谢谢。
以下是相关代码:
启动.cs
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
DbContextOptionsBuilder<PlayerContext> PlayerContextOptions = new DbContextOptionsBuilder<PlayerContext>();
PlayerContextOptions.UseSqlServer(Configuration.GetConnectionString("Default"));
services.AddSingleton(PlayerContextOptions.Options);
services.AddDbContext<PlayerContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Default")));
services.AddCors(options => options.AddPolicy("CorsPolicy",
builder =>
{
builder.AllowAnyMethod().AllowAnyHeader()
.AllowCredentials();
}));
services.AddSignalR();
}
但我根本不知道在我的 Hub 文件中做什么。我什至不知道从哪里开始。我添加了单例,但我不知道如何在我的集线器文件中访问它。这是我想做的,但我愿意接受更好的方法:
MyHub.cs
using (PlayerContext dbContext = new PlayerContext(/* Singleton needs to go here */))
{
// do database stuff
}
解决方案
使用 SignalR 集线器上的依赖注入来注入 EF DbContext 是一个错误的选择,因为 SignalR 集线器本身是一个单例并且不应该具有较低生命周期的依赖项,您最终会收到警告。这意味着,您不能使用 PerRequest/Transient 生命周期范围注册您的 DbContext,只能使用单例。将 DbContext 注册为 Singleton 是一个非常糟糕的选择。制作新的上下文并不昂贵,但是您的具有单例上下文的集线器会在一段时间后成倍增长。
我建议将 DbContextFactory 用于 Hub 类,在您的集线器中从工厂询问新的 DbContext 并将其放入 using 语句。您还可以将工厂本身注册为 Singleton,并使集线器构造函数中的依赖关系更加清晰。
using (var dbContextScope = dbContextScopeFactory.Create(options))
{
//do database stuff
dbContextScope.SaveChanges();
}
推荐阅读
- javascript - 如何修复班级中未定义的错误?
- vue.js - Vue JS:更改后vuex状态不更新组件
- c# - 异步操作已取消但仍需要时间来更新网格
- r - 当从一个简单的一维向量进行子设置时,为什么我们需要连接位置向量?
- c# - 将 ILogger 传递到 .net 核心控制台中的 DI 导致服务未注册错误
- android - Android Studio 3.3 不允许 SDK 版本低于 26 的自适应图标
- sas - 计算置信区间的值
- php - 检查数组是否可以在单次交换中按升序排序
- ajax - 在 rest API 中避免使用 CORS
- sql-server - SQL Server 复制:数据库不存在