-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Function worker's service provider resolves scoped service from the root as singleton #97091
Comments
Tagging subscribers to this area: @dotnet/area-extensions-dependencyinjection Issue DetailsSystem versionFramework version: .Net 8.0 DescriptionIn ASP Core web application runtime, trying to resolve a scoped service from a non-scoped (root) service provider throws an error with the following message:
However, using an instance of Expected behaviorAn exception is thrown when resolving a scoped service from a root provider. Actual behaviorThe service is resolved as a singleton. Code to reproducecsproj file <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.20.1"/>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0"/>
</ItemGroup>
</Project> code using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = new HostBuilder()
.ConfigureFunctionsWorkerDefaults();
builder.ConfigureServices((_, services) => services.AddScoped<IDependency, DependencyImplementation>());
var host = builder.Build();
var depOne = host.Services.GetRequiredService<IDependency>();// Expected to get exception here but it resolved the service
var depTwo = host.Services.GetRequiredService<IDependency>();
var areEqual = depOne == depTwo;// true, received same instance
var scopedDepOne = host.Services.CreateScope().ServiceProvider.GetRequiredService<IDependency>();
var scopedDepTwo = host.Services.CreateScope().ServiceProvider.GetRequiredService<IDependency>();
areEqual = scopedDepOne == scopedDepTwo;// false, received scoped instances as expected
Console.ReadKey();
interface IDependency
{ }
class DependencyImplementation : IDependency
{ }
|
@aventus13 It looks like this failure to validate the scope is a result of calling the |
Thanks for your response, @wcsanders1. However- apologies if it's slightly off topic- isn't this a symptom of a rather wider problem stemming from the design of the DI's default behaviour? Given that scope validation is not enabled by default, it's possible to run into a tricky and potentially dangerous scenario, i.e. resolving a singleton service that takes in a scoped dependency. var services = new ServiceCollection();
services.AddSingleton<ISingletonDependency, SingletonDependencyImplementation>()
.AddScoped<IScopedDependency, ScopedDependencyImplementation>();
var provider = services.BuildServiceProvider()
.CreateScope()
.ServiceProvider;
var singleton = provider.GetRequiredService<ISingletonDependency>(); // Resolves successfully with an injected scoped dependency
class SingletonDependencyImplementation : ISingletonDependency
{
// This should never happen
public SingletonDependencyImplementation(IScopedDependency scoped)
{
// ...
}
} |
I agree @aventus13 that it seems like such behavior would never be wanted. I plan to submit a PR to fix it within this week. |
I think #99199 should resolve this. |
Yes thanks. This is a common issue; work done here to prevent scoped services from being used with a singleton constructor is good as long as it doesn't significantly affect perf in non-development runtime scenarios. As mentioned above, we do try to do error checking but only in development mode: https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs#L330-L331 |
Closing |
System version
Framework version: .Net 8.0
Package causing the problem: Microsoft.Azure.Functions.Worker, v1.20.1
Description
In ASP Core web application runtime, trying to resolve a scoped service from a non-scoped (root) service provider throws an error with the following message:
However, using an instance of
IHost
built byHostBuilder
fromMicrosoft.Extensions.Hosting
doesn't seem to respect service lifetime registration. This can be easily reproduced with the below code. It seems like a bug because the service resolution behavior isn't consistent and can lead to tricky bugs with dependencies relying on scoped context.Expected behavior
An exception is thrown when resolving a scoped service from a root provider.
Actual behavior
The service is resolved as a singleton.
Code to reproduce
csproj file
code
The text was updated successfully, but these errors were encountered: