dotnet / dotnet/aspnetcore

Add a GetService method to ModelValidatorProviderContext class

Open
#62,044 0 comments 0 reactions 0 assignees View on GitHub
api-suggestion area-mvc
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 5h
Merged PRs (30d)
276

Description

## 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:

```C#
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

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

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

```C#
object? IServiceProvider GetService(type type);
```
And now here I can user the **GetService** method without needing to inject **IServiceCollection** interface to the object constructor:

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

## Usage Examples
Here is my complete custom validator provider object:

```C#
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
});
}
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.