在 ASP.NET Core 中使用 FV 和 EF 时获得 "Cannot access a disposed object"
Getting "Cannot access a disposed object" when using FV and EF in ASP.NET Core
我在 ASP.NET 核心应用程序启动时有以下内容:
services.AddDbContext<Context>(x => x.UseSqlServer(connectionString));
services.AddFluentValidation(x => x.RegisterValidatorsFromAssemblyContaining<Startup>());
当我在 FluentValidation 验证器上注入 Entity Framework 上下文时:
public class TestModelValidator : AbstractValidator<TestModel> {
public TestModelValidator(Context context) {
}
}
我收到以下错误:
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
我错过了什么?
如评论中所述,验证器默认实例化为单例,我强烈建议您不要因为性能原因而更改验证器的生命周期——它们的实例化成本非常高。
我更喜欢在 PredicateValidator(又名 Must
)表达式主体中按需实例化轻量级上下文对象——这种方法解决了生命周期差异的问题。
带有 ServiceLocator
模式的示例:
public class MyValidator: AbstractValidator
{
public MyValidator()
{
RuleFor(x => x.Email).Must(email => IsUnique(email)).WithMessage("email must be unique");
}
private IsUnique(string email)
{
var context = !ServiceLocator.Instance.Resolve<Context>();
return context.Users.Any(x => x.Email == email);
}
}
此主题可能对 implementation of service locator with AutoFac 有所帮助。
我在 ASP.NET 核心应用程序启动时有以下内容:
services.AddDbContext<Context>(x => x.UseSqlServer(connectionString));
services.AddFluentValidation(x => x.RegisterValidatorsFromAssemblyContaining<Startup>());
当我在 FluentValidation 验证器上注入 Entity Framework 上下文时:
public class TestModelValidator : AbstractValidator<TestModel> {
public TestModelValidator(Context context) {
}
}
我收到以下错误:
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
我错过了什么?
如评论中所述,验证器默认实例化为单例,我强烈建议您不要因为性能原因而更改验证器的生命周期——它们的实例化成本非常高。
我更喜欢在 PredicateValidator(又名 Must
)表达式主体中按需实例化轻量级上下文对象——这种方法解决了生命周期差异的问题。
带有 ServiceLocator
模式的示例:
public class MyValidator: AbstractValidator
{
public MyValidator()
{
RuleFor(x => x.Email).Must(email => IsUnique(email)).WithMessage("email must be unique");
}
private IsUnique(string email)
{
var context = !ServiceLocator.Instance.Resolve<Context>();
return context.Users.Any(x => x.Email == email);
}
}
此主题可能对 implementation of service locator with AutoFac 有所帮助。