I am building an ASP.NET Core 2 MVC application. A lot of the time I need to make use of dependencies to validate user input. I want my validation methods to be unit testable, and I want to be able to inject mocked dependencies into them. This is something I have previously done in MVC5 to great success but cannot work out the ASP.NET Core 2 equivalent.
This is how I would do it in MVC5:
// the view model to be validated
public class MyViewModel {
public string Username { get; set; }
}
// the model validator that will have dependencies injected into it
public class MyViewModelValidator : ModelValidator
{
private IUserService users;
private MyViewModel model;
public MyViewModelValidator(ModelMetadata metadata, ControllerContext controllerContext, IUserService users)
: base(metadata, controllerContext)
{
this.users = users;
this.model = base.Metadata.Model as MyViewModel;
}
public override IEnumerable<ModelValidationResult> Validate(object container)
{
List<ModelValidationResult> errors = new List<ModelValidationResult>();
if (this.users.CheckExists(this.model.Username))
{
errors.Add(new ModelValidationResult() { MemberName = nameof(MyViewModel.Username), Message = "Username is not available" });
}
return errors;
}
}
// this class works out which validator is required for a given model and
// injects the appropriate dependencies that is resolves using unity in my
// in my case
public class ViewModelValidatorProvider : ModelValidatorProvider
{
private IUnityContainer container;
public ViewModelValidatorProvider() => this.container = DependencyResolver.Current.GetService<IUnityContainer>();
public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
{
if (metadata.ModelType == typeof(MyViewModel))
yield return new MyViewModelValidator(metadata, context, this.container.Resolve<IUserService>());
}
}
// the provider is hooked up in the app start in Global.asax.cs file
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
ModelValidatorProviders.Providers.Add(new ViewModelValidatorProvider());
}
}
Now I can just create an instance of the validator with mocked dependencies and away I go! Sadly ASP.NET Core 2 doesn't have the ModelValidator class and everything I have found so far seems to want to inject dependencies via the controller or to resolve them with in an IValidatableObjects Validate() function.
Is it possible to do this in MVC Core?