Categle
Categle

Reputation: 514

.NET Core DI scope lifetime in Ninject

Edit: Due to lots of users mistakenly taking this as a ASP.NET specific question. Please note that my application is not a web application and I'm not using ASP.NET application (I'm using it's funtionality, that is available in .NET Core as well).


Recently, while configuring an Entity Framework DbContext lifetime in a Ninject DI, I have been digging through the .NET Core Dependency Injection, because it already has a functionality for registering DbContext and can be found here. The default context life time is ServiceLifetime.Scoped.

In the code peek, we can read that in the ASP.NET applications, "scoped" means:

scope is created around each server request

namespace Microsoft.Extensions.DependencyInjection
{
    //
    // Summary:
    //     Specifies the lifetime of a service in an Microsoft.Extensions.DependencyInjection.IServiceCollection.
    public enum ServiceLifetime
    {
        //
        // Summary:
        //     Specifies that a single instance of the service will be created.
        Singleton = 0,
        //
        // Summary:
        //     Specifies that a new instance of the service will be created for each scope.
        //
        // Remarks:
        //     In ASP.NET Core applications a scope is created around each server request.
        Scoped = 1,
        //
        // Summary:
        //     Specifies that a new instance of the service will be created every time it is
        //     requested.
        Transient = 2
    }
}

I'm trying to achieve a similar functionality in Ninject DI but it's really hard to state what would be the equivalent of scoped life time in Ninject, while speaking about .NET Core application (that isn't a web application!).

Ninject has that InRequestScope method, however it's only available for web applications, so it's really different from the .NET Core DI ServiceLifetime.Scoped setting.

Perhaps I would have to create some sort of a custom scope in Ninject, but still - I'm not really able to state, how to achieve exact the same scoped behaviour as in the .NET Core DI. To do that I need to be aware of how is the scoped life time working in context of a .NET Core application in .NET Core DI. My guess would be that there's one instance of a DbContext being created and is being disposed once the application quits.

Hence my questions:

Upvotes: 4

Views: 2150

Answers (2)

Jan Muncinsky
Jan Muncinsky

Reputation: 4408

How is .NET Core DI scope life time setting working and what is it's life cycle?

.Net core internally works with class called ServiceScope. When new request is called (e.g. web request) new instance is created, with new service provider included. During request this service provider is used for dependency resolution. After request is finished, scope is disposed and also its service provider with its resolved services.

  internal class ServiceScope : IServiceScope, IDisposable
  {
    private readonly Microsoft.Extensions.DependencyInjection.ServiceProvider _scopedProvider;

    public ServiceScope(Microsoft.Extensions.DependencyInjection.ServiceProvider scopedProvider)
    {
      this._scopedProvider = scopedProvider;
    }

    public IServiceProvider ServiceProvider
    {
      get
      {
        return (IServiceProvider) this._scopedProvider;
      }
    }

    public void Dispose()
    {
      this._scopedProvider.Dispose();
    }
  }

Is it possible to achieve a similar behaviour in Ninject DI?

As you have already noticed implementing custom scope is way to go. You can check how to do this in another answer:

Ninject - In what scope DbContext should get binded when RequestScope is meaningless?

EDIT:

Principle of .NET Core DI is the same like any other IOC container. It provides dependencies to your objects (MVC controllers etc.) by DI and controls its lifetime.

  • If you specify singleton lifetime for your DbContext than only one is created, provided by DI when requested and hold in memory for whole application/container lifetime.
  • If you specify transient you get new one all the time DbContext is requested.
  • If you specify scoped, lifetime of DbContext is bound to some disposable scope, which is created on the beggining of some logical request (http request in case of asp). When DbContext is requested by DI for the first time, new one is created, hold in memory and you get always the same during subsequent DI requests until the scope is disposed (with end of http request in case of asp) and DbContext with it.

You can find similar parallel with TransactionScope. Here all the sqlCommands within the same TransactionScope are enlisted into the same sql transaction util the scope is disposed/committed.

Upvotes: 3

Anupam Singh
Anupam Singh

Reputation: 1166

There is extension method called InRequestScope, which is available in Ninject.Web.Common nuget package.

InRequestScope : https://github.com/ninject/Ninject.Web.Common/wiki/InRequestScope

You can correlate .net core and ninject DI methods from https://github.com/ninject/Ninject/wiki/Object-Scopes

Upvotes: -2

Related Questions