Skip to content

Add a GetService method to ModelValidatorProviderContext class #62044

Open
@Shoogn

Description

@Shoogn

Add new methos to and existing class

In ASP.NET Core when I'm going to build my own validation provider, I have to register it to work with the built-in on that is provided by ASP.NET Core framework, I have to implement two interfaces:

  1. IModelValidatorProvider
  2. IModelValidator

The IModelValidatorProvider has a method named CreateValidators and accept on parameter of type ModelValidatorProviderContext object.

In this method you may need to resolve some dependency object and to do that you have to inject the IServiceCollection interface and us it like so:

 var validator = _serviceCollection.BuildServiceProvider()
     .GetService(validatorType);

Instead of doing that my suggestion here is to add a new method to this class (ModelValidatorProviderContext) named GetService and should accept one parameter of type Type object

namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
public class ModelValidatorProviderContext
{
    public ModelValidatorProviderContext(ModelMetadata modelMetadata, IList<ValidatorItem> items)
    {
        ModelMetadata = modelMetadata;
        Results = items;
    }
    public ModelMetadata ModelMetadata { get; set; }
    public IReadOnlyList<object> ValidatorMetadata => ModelMetadata.ValidatorMetadata;
    public IList<ValidatorItem> Results { get; }

    // this is the new method
    object? IServiceProvider GetService(type type);
}

Here is the new method:

 object? IServiceProvider GetService(type type);

And now here I can user the GetService method without needing to inject IServiceCollection interface to the object constructor:

 var validatorType = typeof(IValidator<>).MakeGenericType(
     context.ModelMetadata.ModelType);
var object = context.GetService(validatorType)

Usage Examples

Here is my complete custom validator provider object:

public class ModelValidatorProvider : IModelValidatorProvider
{
  // now no need for constructor at al here

    public void CreateValidators(ModelValidatorProviderContext context)
    {
        var validatorType = typeof(IValidator<>).MakeGenericType(
            context.ModelMetadata.ModelType);

  // here is the usage of the new method
        var validator = context.GetService(validatorType)

        if (validator != null)
        {
            var simpleValidatorType = typeof(ModelValidator<>).MakeGenericType(context.ModelMetadata.ModelType);

            var simpleValidator = (IModelValidator?)Activator.CreateInstance(simpleValidatorType, validator);

            context.Results.Add(new ValidatorItem
            {
                IsReusable = true,
                Validator = simpleValidator
            });
        }
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-suggestionEarly API idea and discussion, it is NOT ready for implementationarea-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templates

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions