龙空技术网

ASP.NET Core 依赖注入系列二

opendotnet 144

前言:

如今朋友们对“netguid重复”大体比较关切,朋友们都需要学习一些“netguid重复”的相关资讯。那么小编在网摘上收集了一些关于“netguid重复””的相关资讯,希望各位老铁们能喜欢,大家快快来了解一下吧!

5 ASP.NET Core 依赖注入生命周期

通过依赖注入创建的服务有自己的生命周期,这里有两个问题

1 他们什么时候被创建

2 他们在内存里面保存多久之后才会被GC移除

服务有3种生命周期

1 Transient - 每次请求都会被创建

2 Scoped - 每次每个客户端请求被创建3 Singleton - 只创建一次

6 依赖注入方法

我们常用三个方法来注册服务分别是Transient, Scoped & Singleton

6.1 AddTransient

AddTransient 用Transient方式创建的服务,当服务被请求时创建,这也意味着每次请求DI都会创建一个新的实例,我们在上面的例子使用了AddTransient()方式注入服务,每次在控制器中请求IRepository接口时,都会创建一个新的Repository.cs类对象

6.2 AddScoped

通过AddScoped方法注册的服务不像AddTransient 方法那样每次都被创建,实际上它复用了来自同一客户端的请求,这意味着,如果我们使用这个方法来代替AddTransient,那么Repository.cs类对象将只创建一个,并在浏览器的同一个请求后续中共享该实例,然而,如果我们从另一台电脑的浏览器请求该应用程序,那么(对于这个新客户端)将为每个后续请求创建并共享一个新服务6.3 AddSingleton

AddSingleton方法仅仅在第一次请求时创建一个服务,它会在每个请求中复用,和AddScoped方法不一样,每个跨客户端的请求都会共享该服务

针对AddTransient, AddScoped & AddSingleton方法每个方法都有三种变体

1 <service, implType>() 这种变体为每个依赖项创建一个实现类型的实例,在上面我们已经使用过这中场景

2 <service>()这个变体注册单个类型的对象,我们前面也覆盖到了这种场景

3 <service>(factoryFunc)这种方式使用lambda表达式注册一个服务,我们可以添加我们逻辑,我们将在后面覆盖这种场景

7 通过例子来了解这三种类型

7.1 Transient服务的例子

Transient 服务必须在Program类中使用AddTransient方法注册,我们有2个Transient服务在我们应用程序中,他们是Repository和ProductSum

builder.Services.AddTransient<IRepository, Repository>();builder.Services.AddTransient<ProductSum>();
ProductSum类在指定的构造函数指定了IRepository依赖
namespace AspNetCore.DependencyInjection.Models{ public class ProductSum { public IRepository Repository { get; set; } public ProductSum(IRepository repo) { Repository = repo; } public decimal Total => Repository.Products.Sum(p => p.Price); }}
HomeController指定针对这两个服务的依赖
public HomeController(IRepository repository, ProductSum productSum){ _repository = repository; _productSum = productSum;}

在Repository.cs类中重写ToString()方法,代码如下:

private string guid= Guid.NewGuid().ToString();public override string ToString(){ return guid;}

我们可以通过这个值来判断依赖注入什么时候以及如何创建这个Repository,接下来进入HomeController并且在Index的方法中添加2个ViewBag变量,第一 ViewBag变量将包含从Repository接受的GUID,第二个ViewBag变量包含从ProductSum服务接受的GUID

public IActionResult Index(){ ViewBag.HomeControllerGUID=_repository.ToString(); ViewBag.TotalGUID = _productSum.ToString(); return View(new Repository().Products);}

现在运行应用程序我们将会在页面上看到显示的GUID

我们看到这里2个不同的Guids,因为通过浏览器调用HomeController类每次会创建2个Repository的对象,第一个对象通过Repository服务创建,第二个对象通过ProductSum服务创建(ProductSum在构造函数中有一个IRepository依赖)

这个实例没有共享,我们使用Scoped服务只有一个对象创建,这个对象和ProductSum服务共享, 接下来我们看一下Scoped服务例子

7.2 Scoped服务的例子

为了理解Scoped服务,在Program类中使用AddScoped方法注册Repository服务

builder.Services.AddScoped<IRepository, Repository>();

重新运行应用程序并且你将看到相同的GUIDS, 这意味着ServiceProvider创建了一个Repository对象类并且和ProductSum共享该实例,这是Scoped和Transient服务之间的不同

重新加载页面按下F5,你将看到新的GUID被生成(因为浏览器初始化了一个新的HTTP请求)

7.3 Singleton服务的例子

最后让我们看一下Singleton服务,因此通过使用AddSingleton方法修改Repository服务的注册方式

builder.Services.AddSingleton<IRepository,Repository>();
重新运行你的应用程序,你将看到这两个GUID值是相同的,刷新页面你注意GUID值并没有改变

第一次创建Repository对象它会在后面的每次请求共享该对象,当我们有多个客户端在浏览器中请求HomeController只会创建一个Repository对象并且共享该对象,所有的客户端每次请求都会看到相同的值

标签: #netguid重复