Ninject: HTTP 请求完成后,非一次性 InRequestScope 和 InTransientScope 对象会发生什么?
Ninject: What happens to non-disposable InRequestScope and InTransientScope objects after the HTTP request is finished?
关于这些问题,我已经搜索了很多,here 和很多其他地方,但没有得到我想知道的一切!
- 从 WebApi 项目的角度来看,
InTransientScope
对象何时创建?在 Ninject 文档中声明此类对象在请求时创建,但在处理 HTTP 请求的 Web api 项目中,实例是在请求开始时创建的,因此在这方面它是和InRequestScope
一样吗?
在 WebApi 项目中,是否可以使用知道永远不会被 Ninject 跟踪的 InTransientScope
对象?如果 Ninject 从不跟踪 Transient 对象,那么这个作用域的目的是什么,这些对象在使用后会发生什么?
如果我用 InRequestScope 声明了一个对象并且该对象没有实现 IDisposable
接口,那么在 Web 请求完成后该对象会发生什么情况?它会像 InTransientScope
对象一样被处理吗?
是否将不同的范围用于:WebApi 控制器、存储库(使用单独创建的 InRequestScope
会话)和应用程序服务?
作用域有两个用途:
- 每个范围只允许创建一个对象
- (可选)一旦范围结束就释放对象。
如前所述,处置是可选的。如果它没有实现 IDisposable
接口,它就不会被释放。有很多用例。
InTransientScope
是默认范围 - 如果您未指定另一个范围,则使用该范围。这意味着每次从内核请求类型 A
时都会发生一次激活并返回结果。激活逻辑由紧跟在 Bind
部分(To<...>
、ToMethod(...)
、...)之后的绑定部分指定。
然而,这不一定是在网络请求开始和控制器被实例化的时候。例如,您可以使用工厂或服务位置(p.Ex。ResolutionRoot.Get<Foo>()
)在创建控制器后创建更多对象。简要回答您的问题:
- 时间:当请求发生时,或者每当您的代码直接(
IResolutionRoot.Get(..)
)或通过工厂从 Ninject 请求类型时。由于 InTransientScope
对象没有被跟踪,它们不会被丢弃,但是,如果它们不是一次性的并且整个请求代码只请求一个 IFoo
那么实际上没有明显的区别(除了轻微的性能由于跟踪 InRequestScope()
-ed 对象而命中)
- 只要您不需要确保共享实例 and/or 就可以了。在它们不再被使用后,它们将像您自己
new
自己收集的任何对象一样被垃圾收集。
- 当范围结束时 ninject 将删除对非
IDisposable
对象的弱引用。对象本身不会被触及 - 就像绑定时一样 InTransientScope()
- 这取决于您的具体要求和实施细节。通常需要确保长范围对象不依赖于短范围对象。例如,Singleton-Service 不应依赖于 Request-scoped 对象。作为基本规则,所有内容都应为
InTransientScope()
,除非有特定原因不应该如此。原因将决定使用什么范围...
关于这些问题,我已经搜索了很多,here 和很多其他地方,但没有得到我想知道的一切!
- 从 WebApi 项目的角度来看,
InTransientScope
对象何时创建?在 Ninject 文档中声明此类对象在请求时创建,但在处理 HTTP 请求的 Web api 项目中,实例是在请求开始时创建的,因此在这方面它是和InRequestScope
一样吗? 在 WebApi 项目中,是否可以使用知道永远不会被 Ninject 跟踪的
InTransientScope
对象?如果 Ninject 从不跟踪 Transient 对象,那么这个作用域的目的是什么,这些对象在使用后会发生什么?如果我用 InRequestScope 声明了一个对象并且该对象没有实现
IDisposable
接口,那么在 Web 请求完成后该对象会发生什么情况?它会像InTransientScope
对象一样被处理吗?是否将不同的范围用于:WebApi 控制器、存储库(使用单独创建的
InRequestScope
会话)和应用程序服务?
作用域有两个用途:
- 每个范围只允许创建一个对象
- (可选)一旦范围结束就释放对象。
如前所述,处置是可选的。如果它没有实现 IDisposable
接口,它就不会被释放。有很多用例。
InTransientScope
是默认范围 - 如果您未指定另一个范围,则使用该范围。这意味着每次从内核请求类型 A
时都会发生一次激活并返回结果。激活逻辑由紧跟在 Bind
部分(To<...>
、ToMethod(...)
、...)之后的绑定部分指定。
然而,这不一定是在网络请求开始和控制器被实例化的时候。例如,您可以使用工厂或服务位置(p.Ex。ResolutionRoot.Get<Foo>()
)在创建控制器后创建更多对象。简要回答您的问题:
- 时间:当请求发生时,或者每当您的代码直接(
IResolutionRoot.Get(..)
)或通过工厂从 Ninject 请求类型时。由于InTransientScope
对象没有被跟踪,它们不会被丢弃,但是,如果它们不是一次性的并且整个请求代码只请求一个IFoo
那么实际上没有明显的区别(除了轻微的性能由于跟踪InRequestScope()
-ed 对象而命中) - 只要您不需要确保共享实例 and/or 就可以了。在它们不再被使用后,它们将像您自己
new
自己收集的任何对象一样被垃圾收集。 - 当范围结束时 ninject 将删除对非
IDisposable
对象的弱引用。对象本身不会被触及 - 就像绑定时一样InTransientScope()
- 这取决于您的具体要求和实施细节。通常需要确保长范围对象不依赖于短范围对象。例如,Singleton-Service 不应依赖于 Request-scoped 对象。作为基本规则,所有内容都应为
InTransientScope()
,除非有特定原因不应该如此。原因将决定使用什么范围...