Skip to content

Function worker's service provider resolves scoped service from the root as singleton #97091

@aventus13

Description

@aventus13

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:

Cannot resolve scoped service from root provider

However, using an instance of IHost built by HostBuilder from Microsoft.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

<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
{ }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions