autofac / Autofac.Extensions.DependencyInjection

Autofac implementation of the interfaces in Microsoft.Extensions.DependencyInjection.Abstractions, the .NET Core dependency injection abstraction.
MIT License
196 stars 47 forks source link

In ASP.NET 8, IReadOnlyCollection<> controller parameters do not bind from request body by default in controllers #114

Open IT-CASADO opened 10 months ago

IT-CASADO commented 10 months ago

Describe the bug In ASP.NET 8 a controller with an IReadOnlyCollection<> parameter is not bound from the body of the request by default. An empty collection is seen by the controller. This worked in ASP.NET 6. We are currently trying to migrate from .NET 6 to .NET 8.

IReadOnlyList, Array and potentially some other collection types makes also trouble.

Autofac with ASP.NET 7 is also broken.

To reproduce

You can find a full working repro here: https://github.com/IT-CASADO/ParameterBindingIssue/tree/autofac

Full exception with stack trace:

no exception

Assembly/dependency versions:

    <PackageReference Include="Autofac" Version="7.1.0" />
    <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="8.0.0" />

Additional context Add any other context about the problem here.

alistairjevans commented 10 months ago

First off, thank you for providing the complete re-create project.

I believe what's happening here is that when the IServiceProviderIsService service was added in .NET 7, ASP.NET Core is now asking us whether IEnumerable<WeatherForecast> is a service when it tries to bind parameters to your controller methods.

In Autofac, all supported collection types are always valid services, but when resolved those sets are empty if no registrations have been made (for the WeatherForecast type in this example).

So ASP.NET Core is asking us, "is IEnumerable<WeatherForecast> a service in Autofac", and by Autofac rules the answer is yes.

We aren't likely to change the behaviour of IServiceProvider.IsService here to vary for empty service collections, because that would:

a) Create potentially confusing behaviour if you do want to bind the empty set of services. b) Deviate from documented Autofac behaviour of service collections. c) Require changes in core Autofac to yield the "are there actually any collection services available?" answer.

I'd suggest following the recommendation provided to you by the ASP.NET Core team in that origin issue you created, and applying [FromBody] to the parameter to bypass automatic detection and be explicit.

I'll raise an issue in our docs repo though to add detail on parameter binding in ASP.NET Core now the framework attempts to detect whether something is a service.