.Net依赖注入

一、什么是依赖注入

依赖注入是一种软件设计模式,用于解决一组组件之间的依赖关系。它的目的是实现组件之间的解耦,使得组件更加可复用和可测试。

在依赖注入中,一个组件(称为依赖)不会直接创建或管理它所需要的其他组件,而是通过外部的一个容器(或框架)来注入它所需要的依赖。

二、依赖注入的简单实现

下面创建的是一会需要实现的接口和方法。

public interface IName
{
    public void Name(string NewName);
}

public class MyName : IName
{
    public void Name(string NewName)
    {
        Console.WriteLine($"我叫{NewName},这是MyName");
    }
}

public class HisName : IName
{
    public void Name(string NewName)
    {
        Console.WriteLine($"他叫{NewName},这是HisName");
    }
}

public class GetName
{
    private IName _IName;

    public GetName(IName iName)
    {
        _IName = iName;
    }

    public void NewGetName(string NewName)
    {
        _IName.Name(NewName);
    }
}

 下面我们来看一下普通方式和依赖注入有何区别。

1、普通方式实现

普通方式实现就是使用NEW关键字对方法进行创建,我们来调用GetName类中的NewGetName方法。我们可以看到两行代码就可以搞定了。

GetName getName = new GetName(new MyName());
getName.NewGetName("张三");

2、依赖注入实现

接下来就是使用依赖注入的方式来实现,实现之前我们需要安装一个NuGet 包,下面两个随便安装一个即可。

Microsoft.Extensions.Hosting

 Microsoft.Extensions.DependencyInjection

安装完成后,我们看下面的实现方式,其中ServiceCollection 是一个接口,用于描述一组用于注册服务的方法。 AddScoped表示的是服务生存期,这里为作用域内。这里的GetRequiredService是从泛型中获取服务。

简单来说就是ServiceCollection开始创建,AddScoped将东西存放起来,GetRequiredService获取东西。

ServiceCollection services = new ServiceCollection();//创建服务
services.AddScoped<GetName>();
services.AddScoped<IName, MyName>();
using (ServiceProvider scope = services.BuildServiceProvider())
{
    GetName getName = scope.GetRequiredService<GetName>();
    getName.NewGetName("张三");
}

两种方式总结:

上面两种方式最后的实现效果都是相同的, 但是为什么不推荐使用第一种而推荐使用第二种,第二种比第一种麻烦那么多,最主要的是依赖注入能够将组件之间的依赖关系解耦,使得它们可以独立地进行开发和测试。而普通方式会导致组件之间的紧耦合,难以进行独立测试和开发。

三、服务生存期

上面我们提到了AddScoped是服务生存期,接下来我们来了解一下,服务生存期主要分为三种。

1、暂时

AddTransient暂时生存期服务是每次从服务容器进行请求时创建的,在请求结束时会释放暂时服务。

services.AddTransient<GetName>();
services.AddTransient<IName, MyName>();

2、作用域

AddScoped指定了作用域的生存期,在某个作用域内有效,出了作用域失效。

services.AddScoped<GetName>();
services.AddScoped<IName, MyName>();

3、单例

AddSingleton在首次请求它们时进行创建,或者在向容器直接提供实现实例时进行创建。在处理请求中时,当应用关闭并释放ServiceProvider,就会释放该服务,反之,应用一直存在,那么该服务就一直生效。

services.AddSingleton<GetName>();
services.AddSingleton<IName, MyName>();

四、获取服务的方法

1、GetServices(多个)

获取指定类型的所有服务实例,GetServices方法会返回一个IEnumerable<T>类型的集合,其中包含所有实现了接口的服务实例。

IEnumerable<GetName> getName = scope.GetServices<GetName>();
foreach (GetName name in getName)
{
    name.NewGetName("张三");
}

2、GetService(单个)

获取指定类型的最后一个注册的服务实例,容器会检索已经注册的服务实例,并返回对应类型的实例,如果该类型的服务不存在,它会返回null。

GetName getName = scope.GetService<GetName>();
getName.NewGetName("张三");

3、GetRequiredService(单个)

GetRequiredService方法的作用是从容器中获取指定类型最后一个注册的服务实例。如果容器中不存在该类型的服务,则会抛出一个异常。

GetName getName = scope.GetRequiredService<GetName>();
getName.NewGetName("张三");

五、Web Api中使用依赖注入 

1、构造器注入

首先需要到Program.cs文件中对需要使用的方法进行注册。

builder.Services.AddScoped<GetName>();
builder.Services.AddScoped<IName, MyName>();

 注册完成之后,到API控制器当中创建构造器。

private readonly GetName getname;

public AddsController(GetName getname)
{
    this.getname = getname;
}

[HttpPost]
public void Name()
{
    getname.NewGetName("张三");
}

2、[FromServices]注入

使用构造器注入会有一个问题,就是当前这个API控制器当中如果有多个网络请求,但是只有一个网络请求会用到这个服务,那么在使用不会用到这个服务的网络请求的时候,这个服务还是会被注册。简单来说就是我不管你API控制器当中用不用到这个服务,你对我进行了创建构造器,我都会被创建注册。

所以这里推荐使用[FromServices]注入,它是你这个网络请求需要使用到这个服务,我才会创建注册。

同样的它需要到Program.cs文件中对需要使用的方法进行注册。

builder.Services.AddScoped<GetName>();
builder.Services.AddScoped<IName, MyName>();

注册完成之后到API控制器当中,现在我那个网络请求需要使用到这个服务,我就去那个网络请求那里去配置。这样我不使用这个网络请求就不会对服务创建注册。

[HttpPost]
public void Name([FromServices] GetName getname)
{
    getname.NewGetName("张三");
}

  • 19
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值