gpt4 book ai didi

c# - 注入(inject) DbContext 时无法访问 ASP.NET Core 中已处置的对象

转载 作者:行者123 更新时间:2023-12-01 22:17:35 30 4
gpt4 key购买 nike

在 ASP.NET Core 项目中,我在启动时有以下内容:

  services.AddDbContext<Context>(x => x.UseSqlServer(connectionString));

services.AddTransient<IValidationService, ValidationService>();

services.AddTransient<IValidator<Model>, ModelValidator>();

验证服务如下:

public interface IValidationService {
Task<List<Error>> ValidateAsync<T>(T model);
}

public class ValidationService : IValidationService {
private readonly IServiceProvider _provider;

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

public async Task<List<Error>> ValidateAsync<T>(T model) {
IValidator<T> validator = _provider.GetRequiredService<IValidator<T>>();

return await validator.ValidateAsync(model);
}
}

ModelValidator如下:

public class ModelValidator : AbstractValidator<Model> {
public ModelValidator(Context context) {
// Some code using context
}
}

当我在 Controller 中注入(inject) IValidationService 并将其用作:

List<Error> errors = await _validator.ValidateAsync(order);    

我收到错误:

System.ObjectDisposedException: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur is you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances. Object name: 'Context'.

知道为什么我在 ModelValidator 中使用 Context 时出现此错误吗?

如何解决这个问题?

更新

所以我将代码更改为:

services.AddScoped<IValidationService, ValidationService>();

services.AddScoped<IValidator<Model>, ModelValidator>();

但是我遇到了同样的错误......

更新 - 启动时配置方法内的种子数据代码

所以在配置方法上我有:

if (hostingEnvironment.IsDevelopment())
applicationBuilder.SeedData();

SeedData 扩展名是:

public static class DataSeedExtensions {
private static IServiceProvider _provider;

public static void SeedData(this IApplicationBuilder builder) {
_provider = builder.ApplicationServices;
_type = type;

using (Context context = (Context)_provider.GetService<Context>()) {
await context.Database.MigrateAsync();
// Insert data code
}
}

我错过了什么?

更新 - 可能的解决方案

将我的种子方法更改为以下似乎有效:

using (IServiceScope scope = 
_provider.GetRequiredService<IServiceScopeFactory>().CreateScope()) {
Context context = _provider.GetService<Context>();
// Insert data in database
}

最佳答案

只是猜测导致错误的原因:

您正在使用 DI 和异步调用。如果在调用堆栈中的某个位置返回 void 而不是 Task,则会得到所描述的行为。此时,调用结束并且上下文被释放。因此,请检查您是否有一个异步调用返回 void 而不是 Task。如果更改返回值,ObjectDisposeException 可能会得到修复。

public static class DataSeedExtensions {
private static IServiceProvider _provider;

public static async Task SeedData(this IApplicationBuilder builder) { //This line of code

_provider = builder.ApplicationServices;
_type = type;

using (Context context = (Context)_provider.GetService<Context>()) {

await context.Database.MigrateAsync();
// Insert data code

}

}

并在配置中:

if (hostingEnvironment.IsDevelopment()){
await applicationBuilder.SeedData();
}

有关如何修复此错误的博客文章:Cannot access a disposed object in ASP.NET Core when injecting DbContext

关于c# - 注入(inject) DbContext 时无法访问 ASP.NET Core 中已处置的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38704025/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com