Ninject中的.NET Core DI范围生存期

时间:2018-07-03 22:45:05

标签: c# entity-framework dependency-injection .net-core ninject

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


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

在代码预览中,我们可以了解到在ASP.NET应用程序中,“作用域”的意思是:

  

围绕每个服务器请求创建一个范围

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应用程序(那不是Web时),很难说出Ninject的范围内生命周期的等效值。应用!)。

Ninject具有InRequestScope方法,但是它仅适用于Web应用程序,因此它与.NET Core DI ServiceLifetime.Scoped设置确实不同。

也许我必须创建某种类型的custom scope in Ninject,但是-我仍然无法真正说明如何实现与.NET Core DI中相同的作用域行为。为此,我需要知道范围生命周期在.NET Core DI中的.NET Core应用程序上下文中如何工作。我的猜测是,有一个DbContext实例正在创建,一旦应用程序退出,该实例将被丢弃。

提出我的问题

  • .NET Core DI scope生命周期设置如何工作?生命周期是什么?
  • 是否可以在Ninject DI中实现类似的行为?

2 个答案:

答案 0 :(得分:3)

  

.NET Core DI范围寿命设置如何工作,它是什么?   生命周期?

.Net内核在内部与名为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();
    }
  }
  

是否可以在Ninject DI中实现类似的行为?

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

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

编辑:

.NET Core DI的原理与任何其他IOC容器相同。它通过DI提供对对象(MVC控制器等)的依赖关系,并控制其寿命。

  • 如果您为DbContext指定单例生存期,则只有一个是 由DI根据要求创建并提供,并保存在内存中 整个应用程序/容器的整个生命周期。
  • 如果您指定瞬态,则会得到新的 一直请求DbContext。
  • 如果您指定范围, DbContext的生存期绑定到一些一次性范围,该范围是在某些逻辑请求(在asp情况下为http请求)的开头创建的。当DbContext是 DI首次请求,将创建一个新的,并将其保存在内存中,在此期间您将始终保持相同 后续的DI请求,直到处理范围(在asp情况下以http请求结尾)和DbContext 它。

您可以找到与TransactionScope类似的东西。在这里,同一TransactionScope中的所有sqlCommand都被征用到处置/提交范围的同一sql事务中。

答案 1 :(得分:-2)

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