使用IServiceCollection.AddTransient,IServiceCollection.AddSingleton和IServiceCollectionAddScopped方法的实际场景是什么?

Yaw*_*aza 12 c# asp.net-core

看完这个帖子我也能理解之间的差异AddTransient,AddScoped以及AddSingleton然而,我无法看到他们每个人的实际使用情况.

我的理解是

AddTransient

每次客户端请求时创建一个新实例.

services.AddTransient<IDataAccess, DataAccess>();
Run Code Online (Sandbox Code Playgroud)

每次客户端代码请求时,都会返回一个新的DataAccess对象.更可能是构造函数.

AddTransient的用法

如果我们必须访问数据库来读取和更新它并销毁访问对象(DataAccess),最好使用它AddTransient- 不确定线程​​安全性.

AddScopped

为每个http Web请求创建一个新实例.

AddScopped的用法

 services.AddScoped<ShoppingCart>(serviceProvider => ShoppingCart.GetShoppingCart(serviceProvider));
Run Code Online (Sandbox Code Playgroud)

这意味着每个Web请求将具有其自己的购物车实例,该实体意味着每个用户/客户端将具有用于该http Web请求的其自己的购物车实例.

AddSingleton

为所有http Web请求创建单个实例.

AddSingleton的用法

在示例应用程序中找到此代码,但我不明白它是如何有用的.

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); 
Run Code Online (Sandbox Code Playgroud)

有人可以提供一个体面的实际例子,何时使用AddSingleton并检查我对AddTransient和AddScopped的理解是否正确?

juu*_*nas 16

您对所有3个范围的理解是正确的.

当组件无法共享时,将使用Transient.非线程安全的数据库访问对象就是一个例子.

Scoped可用于Entity Framework数据库上下文.主要原因是从数据库获得的实体将附加到请求中的所有组件看到的相同上下文.当然,如果您打算并行查询,则不能使用Scoped.

Scoped对象的另一个例子是某种RequestContext类,它包含例如调用者的用户名.中间件/ MVC过滤器可以请求它并填写信息,而线下的其他组件也可以请求它,它肯定会包含当前请求的信息.

Singleton组件始终是共享的,因此它们最适合不需要绑定到请求的线程安全组件.例如,可以IOptions访问配置设置.在单个静态实例上HttpClient使用的包装器类也将完全是线程安全的,并且是成为Singleton的良好候选者.SendAsyncHttpClient

请注意,如果您有一个依赖于Scoped组件的Singleton组件,它的依赖关系将在它之前被释放.因此,组件不能依赖于具有比其自身更小范围的另一组件.

  • 如果我读得正确,那么Singleton更喜欢Scoped和Transient(因为不必要地重新创建对象似乎是不必要的),但是对于我们不能使用它的情况(例如,因为非线程安全的代码),我们必须使用另外两个中的一个(取决于我们的需要). (2认同)