.NET Core IServiceScopeFactory.CreateScope() vs IServiceProvider.CreateScope() extension

CreateScope from IServiceProvider resolve IServiceScopeFactory and call CreateScope() on it:

public static IServiceScope CreateScope(this IServiceProvider provider)
{
    return provider.GetRequiredService<IServiceScopeFactory>().CreateScope();
}

So, as said @Evk

functionally both methods are identical

IServiceProvider just wrapped call CreateScope() from IServiceScopeFactory


From what I tested

In ASP.NET Core 5 the following code works:

[HttpGet("/Echo/{word}")]
public IActionResult EchoAndLog(string word, [FromServices] IServiceScopeFactory serviceScopeFactory)
{
    var ipAddress = HttpContext.Connection.RemoteIpAddress;

    // No need to wait for logging, just fire and forget
    Task.Run(async () =>
    {
        await Task.Delay(1000);

        using (var scope = serviceScopeFactory.CreateScope())
        {
            var context = scope.ServiceProvider.GetRequiredService<LogDbContext>();

            var log = new ActivityLog
            {
                IpAddress = ipAddress,
                Endpoint = "Echo",
                Parameter = word
            };

            context.Add(log);
            await context.SaveChangesAsync();                                        
        }
    });

    return Ok(word);
}

Now if you change the IServiceScopeFactory to IServiceProvider it will NOT work:

[HttpGet("/Echo/{word}")]
public IActionResult EchoAndLog(string word, [FromServices] IServiceProvider serviceProvider)
{
    var ipAddress = HttpContext.Connection.RemoteIpAddress;

    // No need to wait for logging, just fire and forget
    Task.Run(async () =>
    {
        await Task.Delay(1000);

        using (var scope = serviceProvider.CreateScope())
        {
            var context = scope.ServiceProvider.GetRequiredService<LogDbContext>();

            var log = new ActivityLog
            {
                IpAddress = ipAddress,
                Endpoint = "Echo",
                Parameter = word
            };

            context.Add(log);
            await context.SaveChangesAsync();                                        
        }
    });

    return Ok(word);
}

You will get the System.ObjectDisposedException exception:

Cannot access a disposed object.

Object name: 'IServiceProvider'.

Which tells me the IServiceProvider will live as long as the request's lifetime (scoped), but this is not the case with IServiceScopeFactory.