C# 依赖项注入不能使用作用域?
我没有太多使用依赖注入的经验,但我正试图在我的一个项目中使用它。当我尝试向我的构造函数添加第二个参数时,我得到一个错误“无法从singleton使用作用域服务“CarbonService…”不确定为什么会出现此错误或缺少什么。谢谢你的帮助 我希望我的timer类能够访问CarbonService对象 Startup.cs:C# 依赖项注入不能使用作用域?,c#,dependency-injection,C#,Dependency Injection,我没有太多使用依赖注入的经验,但我正试图在我的一个项目中使用它。当我尝试向我的构造函数添加第二个参数时,我得到一个错误“无法从singleton使用作用域服务“CarbonService…”不确定为什么会出现此错误或缺少什么。谢谢你的帮助 我希望我的timer类能够访问CarbonService对象 Startup.cs: public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCo
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddDbContext<CarbonDBContext>(o => o.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddHostedService<ValidUntilTimerService>();
services.AddScoped<ICarbonService, CarbonService>(); // I HAVE TRIED USING SINGLETON BUT SAME ERROR
services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true));
}
IHostedService
s被注册为单例。您正在将ICarbonService
注入到validuntilimerservice
中,这意味着您正在将作用域服务注入到单例服务中
如果我们考虑这两种服务的寿命:
- 每个请求创建一次作用域服务。这意味着,当实例化作用域服务时,它将一直保持活动状态,直到请求结束
- 当单例服务被实例化时,它将保持活动状态,直到应用程序关闭
ValidUnitImerService
在您的示例中)被实例化时,其作用域依赖项(ICarbonService
在您的示例中)也被实例化并注入singleton服务。当请求完成时,单例服务保持活动状态,但作用域服务被释放。现在,您的单例服务以一个“死”依赖项结束(\u carbonService
字段)
上述情况是不可能的。这只是一个“如果”的场景。关键是,您不能使用根据请求创建的服务,而该服务可以在没有请求的情况下创建(例如,在应用程序启动时)
现在,这就解释了问题的原因,但让我们看看你能做些什么来解决它
可能的解决方案
您可以使用在ValidUnitImerService
中创建自己的作用域:
public类ValidUntilTimerService:IHostedService,IDisposable
{
专用只读ILogger\u记录器;
私人定时器;
私营IServiceScope工厂(服务范围工厂);;
公共ValidUntilTimerService(ILogger记录器、IServiceScopeFactory服务范围工厂)
{
_记录器=记录器;
_serviceScopeFactory=serviceScopeFactory;
}
// ...
使用(var scope=\u serviceScopeFactory.CreateScope())
{
ICarbonService=scope.ServiceProvider.GetService(typeof(ICarbonService));
// ...
}
// ...
}
您认为该错误的含义可能重复?感谢您的解释。这是有道理的。我提出了你的建议,事情成功了。问题,为什么不更改“services.AddSingleton();”呢?仅供参考,它不会。我试过了
// ADDING THE SECOND PARAMETER TO THIS CONSTRUCTOR CAUSES THE ERROR.
public class ValidUntilTimerService : IHostedService, IDisposable
{
private readonly ILogger _logger;
private Timer _timer;
private ICarbonService _carbonService;
public ValidUntilTimerService(ILogger<ValidUntilTimerService> logger, ICarbonService carbonService)
{
_logger = logger;
_carbonService = carbonService;
}
...
}
public interface ICarbonService
{
WattTime ReadCarbon();
void SaveCarbon(int carbonIndex);
}
public class CarbonService : ICarbonService
{
private IConfiguration _configuration;
private readonly CarbonDBContext _dbcontext;
public CarbonService(IConfiguration configuration, CarbonDBContext dbContext)
{
_configuration = configuration;
_dbcontext = dbContext;
}
public WattTime ReadCarbon()
{
var wt = new WattTime();
...
return wt;
}
public void SaveCarbon(int carbonIndex)
{
...
}
}