I am using the FluentValidation library to enforce a unique constraint on one of my models:
public class Foo {
// No two Foos can have the same value for Bar
public int Bar { get; set; }
}
public class FooValidator : AbstractValidator<Foo> {
public FooValidator(ApplicationDbContext context) {
this.context = context;
RuleFor(m => m.Bar)
.Must(BeUnique).WithMessage("Bar must be unique!");
}
private readonly ApplicationDbContext context;
public bool BeUnique(int bar) {
return !context.Foos.Any(foo => foo.Bar == bar);
}
}
The ApplicationDbContext
value is injected using StructureMap. To make sure that the context is disposed of at the end of every request, I attempted to call ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects()
in the EndRequest
handler for my application.
Unfortunately, it appears as though the Application_EndRequest
method is called before my validator class is able to do its job and the context is disposed by the time FooValidator.BeUnique
is executed.
Is there a better way to perform database-dependent validations with the FluentValidation library, or is the only solution to move this logic elsewhere (either to the controller action, the DB itself, or maybe elsewhere)?
To inject a validator for a specific model, you should register the validator with the service provider as IValidator<T> , where T is the type of object being validated. This validator can be registered as IValidator<User> in your application's startup routine by calling into the .
Advantages of using Fluent ValidationsSpeed of development- It is easy to work with. Decoupling validation rules and models- Fluent Validation allows you to separate validation rules from your model and helps you structure the rules so that they are nice and readable.
FluentValidation is a .NET library for building strongly-typed validation rules. It Uses a fluent interface and lambda expressions for building validation rules. It helps clean up your domain code and make it more cohesive, as well as giving you a single place to look for validation logic.
Maybe the validator is not http scoped (but singleton) and it is not recreated/injected with a new context? In this case it tries to use a disposed context from a previous request.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With