获取"无法访问已处置的对象"在ASP.NET Core中使用FV和EF时

时间:2016-07-29 17:38:57

标签: asp.net-core fluentvalidation

我在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

我错过了什么?

1 个答案:

答案 0 :(得分:1)

正如评论中所提到的,验证器默认情况下实例化为单例,我强烈建议您不要因性能原因而更改验证器生命周期 - 实例化它们非常昂贵。

我更喜欢在 PredicateValidator (又名Must)表达式主体中按需实例化轻量级Context对象 - 这种方法解决了生命不一致的问题。

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有用。