c# - 为什么我不能在需要相同上下文的控制器中注入需要 httpclient 和 EF 上下文的服务
问题描述
我有一个需要服务的控制器,所以我注入它。该服务需要一个HttpClient
所以我注入它。它们都需要 EF 上下文。
我确实HttpClient
为该服务添加了 at Startup 。但是我有以下错误。
在Startup
:
services.AddHttpClient<IMyService, MyService>();
在MyService
课堂上
private readonly HttpClient _httpClient;
private readonly ReadContext _readContext;
public MyService(HttpClient httpClient, ReadContext readContext)
{
_httpClient = httpClient;
_readContext = readContext;
}
在我的控制器中:
private readonly IMyService _myService;
public MyController(ReadContext ctx, IMyService myService)
{
_ctx = ctx;
_myService = myService;
}
错误:
System.InvalidOperationException: Cannot resolve scoped service 'MyApp.Backend.ReadContext' from root provider.
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(Type serviceType, IServiceScope scope, IServiceScope rootScope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.Microsoft.Extensions.DependencyInjection.ServiceLookup.IServiceProviderEngineCallback.OnResolve(Type serviceType, IServiceScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method(Closure , IServiceProvider , Object[] )
at Microsoft.Extensions.Http.DefaultTypedHttpClientFactory`1.CreateClient(HttpClient httpClient)
并不是说当服务被注入不需要的控制器时,这是可行的ReadContext
。这里似乎有一些解决循环。
更新
从评论中,我了解到AddHttpClient<T>
创建的实例的T
生命周期与HttpClient
aspnet 核心创建和管理的生命周期相同DbContext
,该生命周期比实际请求的生命周期长。很公平。那么如何将一个注入HttpClient
到临时服务中呢?
更新2
根据该博客,我可以注入 in 的一个实例,IHttpClientFactory
而MyService
不是使用services.AddHttpClient();
. 确实,错误消失了。我将不得不做一些阅读以了解向工厂询问实例HttpClient
或注入实例之间的区别。
解决方案
注册MyService
为范围:
services.AddScoped<IMyService, MyService>();
然后,只需注册您HttpClient
的MyService
:
services.AddHttpClient<MyService>();
您现在的做法MyService
是在单例范围内创建,这使得无法注入像您的上下文这样的范围依赖项。
或者,您可以改为注入IServiceProvider
并使用服务定位器反模式来获取您的上下文。它被称为反模式是有原因的,所以这不是最好的处理方式,但是如果您的服务是单例范围的,则没有其他方法:
public class MyService : IMyService
{
private readonly HttpClient _client;
private readonly IServiceProvider _services;
public MyService(HttpClient client, IServiceProvider services)
{
_client = client;
_services = services;
}
}
然后,稍后:
using (var scope = _services.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<ReadContext>();
// do something
}
推荐阅读
- machine-learning - model.save() 是保存最后一个 epoch 还是最好 epoch 的模型?
- amazon-web-services - 在 AWS。我将结果整理到主节点上,然后准备写入 S3,但出现以下错误:
- php - 服务器代码产生过多的 php 实例
- c - Scanf 读取超过预定义字符数组大小的字符串
- javascript - 使用 .map 从 JSON 对象初始化 TypeScript 对象抱怨 myclass.myFunction 不是函数
- docker - 在 i386/debian Docker 映像上安装 libboost-all-dev 时未满足的依赖关系
- css - 将 CSS 过渡添加到我的所有课程
- java - Java中的递归方法提供不正确的输出
- mysql - 按具有重复值的 CASE 排序
- android - 想在 Kotlin 中显示一个小斜体 i(数学符号)