Description
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 isinternal
. See DefaultProblemDetailsFactory.cs for more info. - The only way I found to add the
DefaultProblemDetailsFactory
to the container is by calling theAddMvcCore
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 anyProblemDetailsFactory
with the container. See ProblemDetailsServiceCollectionExtensions.cs for more info. - The
IProblemDetailsService
interface does not directly use theProblemDetailsFactory
, yet leveraging the factory to create an instance of theProblemDetails
class before setting theProblemDetailsContext
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 registeredProblemDetailsFactory
implementation). For example, adding thetraceId
and leveraging theApiBehaviorOptions.ClientErrorMapping
property to get/set some default values. - I find it a little confusing that the
ProblemDetailsFactory
andProblemDetails
classes are part of MVC while their reach now goes beyond MVC.- The
ProblemDetailsContext
class references theProblemDetails
class. - The
IProblemDetailsService
interface uses theProblemDetailsContext
class. - Both
ProblemDetailsContext
andIProblemDetailsService
are not part of MVC.
- The
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 topublic
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 haveAddMvcCore
call this new method instead. - Another option would be to add a
TryAddSingleton<ProblemDetailsFactory, DefaultProblemDetailsFactory>()
call in theAddProblemDetails
method to register theDefaultProblemDetailsFactory
on top of theIProblemDetailsService
.
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.