Skip to content

Allow using the DefaultProblemDetailsFactory without adding MVC Core #49982

Closed
@Carl-Hugo

Description

@Carl-Hugo

Summary

I want to use the DefaultProblemDetailsFactory class without calling the AddMvcCore method.

Motivation and goals

I aim to leverage a ProblemDetailsFactory implementation (say the DefaultProblemDetailsFactory class) without adding MVC services to a Minimal API project.

More context: I'm updating older code to support .NET 7-8 that uses the ProblemDetailsFactory to generate ProblemDetails instances. The workaround was to call AddMvcCore then, which was kinda ok since there was only MVC before. However, now that we have Minimal APIs, adding MVC dependencies to a non-MVC project makes no sense.

Here are a few facts:

  • The visibility modifier of the DefaultProblemDetailsFactory class is internal. See DefaultProblemDetailsFactory.cs for more info.
  • The only way I found to add the DefaultProblemDetailsFactory to the container is by calling the AddMvcCore method. See MvcCoreServiceCollectionExtensions.cs for more info.
  • In a non-MVC project, the AddMvcCore method adds a lot of dependencies for no reason.
  • The newer AddProblemDetails method does not register any ProblemDetailsFactory with the container. See ProblemDetailsServiceCollectionExtensions.cs for more info.
  • The IProblemDetailsService interface does not directly use the ProblemDetailsFactory, yet leveraging the factory to create an instance of the ProblemDetails class before setting the ProblemDetailsContext would allow consumers to reuse .NET building blocks, making the creation of the objects more "standard" and in line with other parts of .NET (a.k.a. reusing the registered ProblemDetailsFactory implementation). For example, adding the traceId and leveraging the ApiBehaviorOptions.ClientErrorMapping property to get/set some default values.
  • I find it a little confusing that the ProblemDetailsFactory and ProblemDetails classes are part of MVC while their reach now goes beyond MVC.
    • The ProblemDetailsContext class references the ProblemDetails class.
    • The IProblemDetailsService interface uses the ProblemDetailsContext class.
    • Both ProblemDetailsContext and IProblemDetailsService are not part of MVC.

In scope

Allow registering the DefaultProblemDetailsFactory with the container without calling the AddMvcCore method.

  • This could be as simple as changing the DefaultProblemDetailsFactory class visibility to public and letting the non-MVC consumers add the binding themselves.
  • Another option would be to create a public extension method named AddDefaultProblemDetailsFactory that adds the binding and have AddMvcCore call this new method instead.
  • Another option would be to add a TryAddSingleton<ProblemDetailsFactory, DefaultProblemDetailsFactory>() call in the AddProblemDetails method to register the DefaultProblemDetailsFactory on top of the IProblemDetailsService.

Or any other ways you think would be best. I am ok with creating a PR if there is some interest.

Out of scope

  • Everything else.

Risks / unknowns

I don't see that many risks, if any.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs: Attention 👋This issue needs the attention of a contributor, typically because the OP has provided an update.area-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesdesign-proposalThis issue represents a design proposal for a different issue, linked in the description

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions