简体   繁体   English

Ninject中的.NET Core DI范围生命周期

[英].NET Core DI scope lifetime in Ninject

Edit: Due to lots of users mistakenly taking this as a ASP.NET specific question. 编辑:由于许多用户错误地将此视为ASP.NET特定问题。 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). 请注意,我的应用程序不是Web应用程序,我没有使用ASP.NET应用程序(我正在使用它的功能,也可以在.NET Core中使用)。


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 . 最近,在Ninject DI中配置实体框架DbContext生命周期时,我一直在挖掘.NET Core依赖注入,因为它已经具有注册DbContext的功能,可以在这里找到。 The default context life time is ServiceLifetime.Scoped . 默认上下文生命周期是ServiceLifetime.Scoped

In the code peek, we can read that in the ASP.NET applications, "scoped" means: 在代码窥视中,我们可以读到在ASP.NET应用程序中,“作用域”意味着:

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 DI中实现类似的功能,但在谈论.NET Core应用程序( 不是Web应用程序时 )时,很难说明在Ninject中等效的生存时间是多少。

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. Ninject具有InRequestScope方法,但它仅适用于Web应用程序,因此它与.NET Core DI ServiceLifetime.Scoped设置完全不同。

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. 也许我必须在Ninject中创建某种自定义作用域 ,但仍然 - 我真的无法说明,如何实现与.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. 为此,我需要了解在.NET Core DI中的.NET Core应用程序的上下文中,作用域的生命周期是如何工作的。 My guess would be that there's one instance of a DbContext being created and is being disposed once the application quits. 我的猜测是,有一个DbContext实例正在创建,并在应用程序退出后处理。

Hence my questions : 因此我的问题

  • How is .NET Core DI scope life time setting working and what is it's life cycle? .NET Core DI scope生命周期设置如何工作以及它的生命周期是什么?
  • Is it possible to achieve a similar behaviour in Ninject DI? 是否有可能在Ninject DI中实现类似的行为?

How is .NET Core DI scope life time setting working and what is it's life cycle? .NET Core DI范围生命周期设置如何工作以及它的生命周期是什么?

.Net core internally works with class called ServiceScope . .Net核心内部使用名为ServiceScope类。 When new request is called (eg web request) new instance is created, with new service provider included. 当调用新请求(例如,Web请求)时,创建新实例,其中包括新的服务提供者。 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? 是否有可能在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? Ninject - 当RequestScope无意义时,DbContext应在什么范围内绑定?

EDIT: 编辑:

Principle of .NET Core DI is the same like any other IOC container. .NET Core DI的原理与任何其他IOC容器相同。 It provides dependencies to your objects (MVC controllers etc.) by DI and controls its lifetime. 它通过DI为您的对象(MVC控制器等)提供依赖关系并控制其生命周期。

  • 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. 如果为DbContext指定单独生存期,则只创建一个生命周期,由DI在请求时提供,并在整个应用程序/容器生存期内保留在内存中。
  • If you specify transient you get new one all the time DbContext is requested. 如果指定transient,则在请求DbContext时始终会获得新的。
  • 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). 如果指定作用域,则DbContext的生存期绑定到某个一次性作用域,该作用域是在某个逻辑请求的开始时创建的(在asp的情况下为http请求)。 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. 当DI第一次请求DbContext时,会创建一个新的,保留在内存中,并且在后续DI请求期间始终保持相同,直到范围被处理(在asp的情况下为http请求结束)和DbContext。

You can find similar parallel with TransactionScope. 您可以在TransactionScope中找到类似的并行。 Here all the sqlCommands within the same TransactionScope are enlisted into the same sql transaction util the scope is disposed/committed. 这里,同一TransactionScope中的所有sqlCommands都被列入相同的sql事务,并且该范围被处置/提交。

There is extension method called InRequestScope, which is available in Ninject.Web.Common nuget package. 有一个名为InRequestScope的扩展方法,它可以在Ninject.Web.Common nuget包中找到。

InRequestScope : https://github.com/ninject/Ninject.Web.Common/wiki/InRequestScope 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 您可以从https://github.com/ninject/Ninject/wiki/Object-Scopes关联.net核心和ninject DI方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM