.NET Core DI 作用域生命周期 Ninject

.NET Core DI scope lifetime in Ninject

编辑:由于许多用户错误地将此视为 ASP.NET 特定问题。请注意,我的应用程序不是 Web 应用程序,我没有使用 ASP.NET 应用程序(我使用的是它的功能,在 .NET Core 中也可用)。


最近,在 Ninject DI 中配置 Entity Framework DbContext 生命周期时,我一直在研究 .NET Core 依赖注入,因为它已经具有注册 DbContext 的功能并且可以找到 here。默认上下文生命周期为 ServiceLifetime.Scoped.

在代码查看中,我们可以看到在 ASP.NET 应用程序中,"scoped" 表示:

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

我正在尝试在 Ninject DI 中实现类似的功能,但是在谈论 .NET Core 应用程序时,很难说出 Ninject 中相当于作用域生命周期的时间(那不是网络应用程序!)。

Ninject 有那个 InRequestScope 方法,但是它只适用于 Web 应用程序,所以它与 .NET Core DI ServiceLifetime.Scoped 设置确实不同。

也许我必须创建某种 custom scope in Ninject,但我仍然不能真正说明如何实现与 .NET Core DI 中完全相同的作用域行为。为此,我需要了解作用域生命周期在 .NET Core DI 中的 .NET Core 应用程序上下文中是如何工作的。我的猜测是,有一个正在创建的 DbContext 实例,并在应用程序退出后被释放。

因此我的问题:

Ninject.Web.Common nuget 包中有名为 InRequestScope 的扩展方法。

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

您可以关联 .net 核心和 ninject DI 方法 来自 https://github.com/ninject/Ninject/wiki/Object-Scopes

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

.Net 核心在内部与 class 一起工作,称为 ServiceScope。当调用新请求(例如网络请求)时,将创建新实例,其中包括新的服务提供者。在请求期间,此服务提供者用于依赖项解析。请求完成后,处理范围及其服务提供者及其解析的服务。

  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?

正如您已经注意到的那样,实现自定义范围是可行的。您可以在另一个答案中查看如何执行此操作:

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

编辑:

.NET Core DI的原理和其他IOC容器一样。它通过 DI 为您的对象(MVC 控制器等)提供依赖性并控制其生命周期。

  • 如果您为 DbContext 指定单例生存期,那么只有一个是 创建,在请求时由 DI 提供并保存在内存中 整个 application/container 一生。
  • 如果你指定瞬态你得到新的 一直请求 DbContext。
  • 如果您指定范围, DbContext 的生命周期绑定到某个一次性范围,该范围是在某些逻辑请求(在 asp 的情况下为 http 请求)的开始时创建的。当 DbContext 是 DI 第一次请求,创建新的,保存在内存中,并且在期间你总是一样的 后续的 DI 请求,直到范围被处理(在 asp 的情况下,http 请求结束)和 DbContext 它。

您可以找到与 TransactionScope 相似的并行。在这里,同一个 TransactionScope 中的所有 sql 命令都被征募到同一个 sql 事务中,范围是 disposed/committed.