Skip to content

Add a GetService method to ModelValidatorProviderContext class #62044

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Shoogn opened this issue May 21, 2025 · 0 comments
Open

Add a GetService method to ModelValidatorProviderContext class #62044

Shoogn opened this issue May 21, 2025 · 0 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates

Comments

@Shoogn
Copy link

Shoogn commented May 21, 2025

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
            });
        }
    }
@Shoogn Shoogn added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label May 21, 2025
@github-actions github-actions bot added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label May 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates
Projects
None yet
Development

No branches or pull requests

1 participant