Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create scope factory in asp.net core

I want to create scoped container in asp.net core and use it in 2 methods of my singleton method.

I've tried create this in each method of sigleton. it works, but i think it is overhead.

var scopeFactory = _serviceProvider.GetService<IServiceScopeFactory>();
var scope = scopeFactory.CreateScope();
var scopedContainer = scope.ServiceProvider;

I write it in each method when i need it. I think it is logic mistake. Please, explain me how to do it correct? thank you

like image 269
Giacomo Avatar asked Mar 27 '19 15:03

Giacomo


People also ask

What is scope factory?

A factory for creating instances of IServiceScope, which is used to create services within a scope.

What is CreateScope in .NET Core?

With ASP.NET Core, you can optionally create and manage your own scopes that by calling CreateScope() for when you need services that live outside of a HttpRequest . It is clear that calling IServiceScopeFactory. CreateScope() will create a new IServiceScope every time; however, does calling the IServiceProvider.

What is IServiceCollection in .NET Core?

AddScoped(IServiceCollection, Type, Type) Adds a scoped service of the type specified in serviceType with an implementation of the type specified in implementationType to the specified IServiceCollection.

What is difference between AddTransient and AddScoped?

AddTransient() - This method creates a Transient service. A new instance of a Transient service is created each time it is requested. AddScoped() - This method creates a Scoped service. A new instance of a Scoped service is created once per request within the scope.


1 Answers

It is technically not incorrect the way you do it. If you are within a singleton service and you need to access scoped services, then you should create a new service scope and retrieve the services from that scope’s service provider. And when you are done, you should also dispose the scope.

In practice, you can simplify this a bit. You should avoid having to inject IServiceProvider directly into a service. Instead, you can just inject the IServiceScopeFactory directly. And then you should also create the scope with a using statement to make sure that it is disposed properly after use.

So an example singleton service could look like this:

public class ExampleSingletonService
{
    private readonly IServiceScopeFactory _serviceScopeFactory;

    public ExampleSingletonService(IServiceScopeFactory serviceScopeFactory)
    {
        _serviceScopeFactory = serviceScopeFactory;
    }

    public async Task DoSomethingAsync()
    {
        using (var scope = _serviceScopeFactory.CreateScope())
        {
            var db = scope.ServiceProvider.GetService<MyDbContext>();

            db.Add(new Foo());
            await db.SaveChangesAsync();
        }
    }
}

As you can see, there isn’t really that much overhead for this. But of course this makes you think twice about whether you want to use a scoped service within a singleton or not.

like image 114
poke Avatar answered Oct 04 '22 23:10

poke