繁体   English   中英

ASP.NET Core如何将依赖注入到其他类的构造函数中?

[英]How does ASP.NET Core inject dependencies into the constructor of other classes?

我是 ASP.NET Core 的新手,到目前为止我已经学习了一个月。

然而,依赖注入是我似乎无法理解的一件事,对我来说它几乎感觉就像魔术一样。

我为我的身份验证方法创建了一个存储库 class。 在这里, DataContext以某种方式从某个地方(我不知道从哪里)被注入到构造函数中。

public class AuthRepository : IAuthRepository
{
    private readonly DataContext _context;

    public AuthRepository(DataContext context)
    {
        _context = context;
    }

    public async Task<User> Login(string username, string password)
    {
        var user = await _context.Users.FirstOrDefaultAsync(x => x.Username == username);

        if (user == null)
            return null;

        if (!VerifyPasswordHash(password, user.PasswordHash, user.PasswordSalt)) 
            return null;

        return user;
    }
}

在 controller 的构造函数中,我添加了存储库和配置,因为我在 controller class 中的方法使用了它们。

[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
    private readonly IAuthRepository _repo;
    private readonly IConfiguration _config;

    public AuthController(IAuthRepository repo, IConfiguration config)
    {
        _config = config;
        _repo = repo;
    }
}

现在在Startup class 我告诉我想在ConfigureServices()中使用哪些依赖项。

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<DataContext>(x =>
            x.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
        services.AddControllers();
        services.AddCors();
        services.AddScoped<IAuthRepository, AuthRepository>();
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8
                        .GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
                    ValidateIssuer = false,
                    ValidateAudience = false
                };
            });
    }
}

一个月前,我确实尝试使用Microsoft.Extensions.DependencyInjection在控制台应用程序中设置依赖注入容器。 但是,如果我没记错的话,它并没有自动将依赖项注入到我的其他类的构造函数中。 但是 ASP.NET 似乎确实这样做了。 ASP.NET 中发生了什么,它们被自动注入到类的构造函数中?

这不是一个真正适合 SO 和该平台给出的简短答案的问题。 您应该搜索更多内容并在其他地方阅读有关这些内容非常深刻的内容。 我会尽力回答你所问的。

有两种不同的依赖注入模式。 构造函数注入和服务定位器。 大多数 DI 工具(有时称为containers )都支持它们。 在构造函数注入中,您在构造函数中放置任何要求,然后在请求已注册 class 的实例时将它们注册到容器中,容器将实例化该 class 并提供依赖项。 请记住,所有依赖项都应该在容器中注册,并且您不要实例化它们。

当您调用像AddScoped()这样的方法时,您正在调用 ASP.Net 核心的服务容器并注册该 class。 它自动用于实例化控制器和其他类。 控制器本身是自动注册的。

您可以在 ASP.Net 核心或其他 .Net 平台(如SimpleInjectorAutoFac )中使用其他 DI 工具。 查看他们的文档以获取有关如何使用它们的更多信息。 在其他项目类型中,这些库可能会更好地工作。

这是一个非常简短的解释,我希望这会有所帮助。

这真的很简单。 您向 DI 容器注册依赖项。 然后,当您从 DI 容器中提取这些依赖项时,它会实例化它们(根据它们各自的生命周期),从 DI 容器中提供任何必要的依赖项。

在 Core 中,这些是您的“服务”,而 DI 容器是您的“服务集合”。 当 ASP.NET 内核实例化 controller 时,它会从服务集合中查找它需要的服务(在构造函数中指定的类依赖项)并将其传入。

从您的控制台应用程序的角度来看。 您在服务集合中注册了一堆东西。 如果你只是做new MyService() ,你显然不会得到任何注入,因为你没有使用 DI 容器。 但是,如果您执行以下操作:

serviceProvider.GetRequiredService<MyService>();

然后服务提供者(DI 容器)尝试实例化MyService ,并且在此过程中,还将拉取MyService所具有的任何依赖项以注入这些依赖项。 如果这些依赖项也有依赖项,那么它会提取这些依赖项来实例化它需要实例化MyService的依赖项。 等等等等。

总而言之,DI 容器可以完成工作,这就是重点。 单个类不需要知道或关心它们的依赖项是如何创建或提供的。 他们只是宣传他们有依赖关系(通过构造函数参数),而 DI 容器会根据需要提供这些依赖关系。

暂无
暂无

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

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