c# - 无法使用单例的范围服务
问题描述
我正在尝试在托管服务中使用 DBContext 但收到此错误。我试图遵循这个 公认的答案,但不知何故它不起作用,我不确定我做错了什么。
我是 .net 的新手,请引导我走向正确的方向。
未处理的异常:System.InvalidOperationException:无法使用单例“Microsoft.AspNetCore.Hosting.Internal.HostedServiceExecutor”中的范围服务“StatusApp.Context.DBContext”。
public class TokenService : IHostedService
{
public IConfiguration _Configuration { get; }
protected IMemoryCache _cache;
private Timer _timer;
public IHttpClientFactory _clientFactory;
public DBContext _DBcontext;
private readonly IServiceScopeFactory _scopeFactory;
public TokenService(IConfiguration configuration, IMemoryCache memoryCache, IHttpClientFactory clientFactory, DBContext DBcontext, IServiceScopeFactory scopeFactory)
{
_Configuration = configuration;
_cache = memoryCache;
_clientFactory = clientFactory;
_scopeFactory = scopeFactory;
_DBcontext = _scopeFactory.CreateScope().ServiceProvider.GetRequiredService<DBcontext>();
}
public Task StartAsync(CancellationToken cancellationToken)
{
_timer = new Timer(getOrg, null, 0, 1000);
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
//Timer does not have a stop.
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
public async Task getOrg()
{
var request = new HttpRequestMessage(HttpMethod.Get, "organizations");
var response = await _client_NP.SendAsync(request);
var json = await response.Content.ReadAsStringAsync();
OrganizationsClass.OrgsRootObject model = JsonConvert.DeserializeObject<OrganizationsClass.OrgsRootObject>(json);
foreach (var item in model.resources)
{
var g = Guid.Parse(item.guid);
var x = _DBcontext.Organizations.FirstOrDefault(o => o.OrgGuid == g);
if (x == null)
{
_DBcontext.Organizations.Add(new Organizations
{
OrgGuid = g,
Name = item.name,
CreatedAt = item.created_at,
UpdatedAt = item.updated_at,
Timestamp = DateTime.Now,
Foundation = 3
});
}
else if (x.UpdatedAt != item.updated_at)
{
x.CreatedAt = item.created_at;
x.UpdatedAt = item.updated_at;
x.Timestamp = DateTime.Now;
}
}
await _DBcontext.SaveChangesAsync();
}
}
解决方案
你快到了,但你已经作为' 构造函数DBContext
中的依赖项离开了。TokenService
删除它,您将不再收到错误。
公共令牌服务( IConfiguration 配置, IMemoryCache 内存缓存, IHttpClientFactory 客户端工厂,DBContext DBContext,IServiceScopeFactory 范围工厂)
但是,您并没有完全遵循DbContext
在单例服务中处理 ' 的建议。与其在构造函数中创建单个实例DBContext
并将其存储为字段,不如在需要时创建范围和对应的范围DBContext
。在你的情况下,这就是getOrg
方法。
请按照以下步骤实现:
从您的班级中删除该
_DBcontext
字段:TokenService
公共DBContext _DBcontext;从
TokenService
构造函数中删除关联的赋值:_DBcontext = _scopeFactory.CreateScope().ServiceProvider.GetRequiredService<DBcontext>();在
getOrg
中,创建一个作用域,解析一个实例DBContext
,最后处置作用域:public async Task getOrg() { var request = new HttpRequestMessage(HttpMethod.Get, "organizations"); var response = await _client_NP.SendAsync(request); var json = await response.Content.ReadAsStringAsync(); OrganizationsClass.OrgsRootObject model = JsonConvert.DeserializeObject<OrganizationsClass.OrgsRootObject>(json); using (var scope = _scopeFactory.CreateScope()) { var dbContext = scope.ServiceProvider.GetRequiredService<DBcontext>(); foreach (var item in model.resources) { var g = Guid.Parse(item.guid); var x = dbContext.Organizations.FirstOrDefault(o => o.OrgGuid == g); if (x == null) { dbContext.Organizations.Add(new Organizations { OrgGuid = g, Name = item.name, CreatedAt = item.created_at, UpdatedAt = item.updated_at, Timestamp = DateTime.Now, Foundation = 3 }); } else if (x.UpdatedAt != item.updated_at) { x.CreatedAt = item.created_at; x.UpdatedAt = item.updated_at; x.Timestamp = DateTime.Now; } } await dbContext.SaveChangesAsync(); } }
上面的代码没有使用该_DBContext
字段,而是创建了一个局部的、范围适当的变量dbContext
并使用它。
推荐阅读
- javascript - 散景:使用 CustomJS 从复选框组更新散点图以过滤源
- python - “kafka.errors.NoBrokersAvailable:NoBrokersAvailable”问题
- batch-file - windows批量转义整个字符串
- linux - 无法使用管道将值从 bash 传递到 curl
- javascript - 物化CSS FormSelect如何在按下键盘时获得第二个字母
- javascript - 每次值更改时如何将更新的道具值传递给孩子?
- php - 为什么 pre_get_posts 钩子中的 is_main_query() 在主循环中不返回 true?
- json - 重新格式化 JSON 对象
- docker - 没有从主机到 docker 容器的网络
- kubernetes - 在缩小 k8s pod 副本之后,k8s 如何选择终止哪个?