如何向构造函数控制器注入依赖项

时间:2021-06-25 09:25:31

标签: api asp.net-core dependency-injection singleton

我正在尝试配置一个 API,控制器使用依赖注入将对象注入该控制器

public class BaseAPIController
{
    private readonly Repository _repository;
    public BaseAPIController(Repository repository)
    {
        _repository = repository;
    }

    // some common functions and properties are declared here
}
public class AccountController : BaseAPIController
{
    public AccountController(Repository repository) : base(repository)
    {  }
}

但它抛出一个异常,告诉“某些服务无法构建...”

我尝试了一个使用 ILogger<Repository> 而不是使用 Repository 实例的解决方案,然后它可以正常运行

public class AccountController : BaseAPIController
{
    public AccountController(ILogger<Repository> repository) : base(repository)
    {  }
}

startup.cs 代码中的注册服务

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddScoped<IRepository, Repository>();
    services.AddSingleton<WeatherForecastController, WeatherForecastController>();
}

和Repository类的声明

public interface IRepository
{
    void DoSomething1();
    void DoSomething2();
    void DoSomething3();        
}
public class Repository : IRepository
{
    public readonly string _connectionString;

    public Repository(string connectionString)
    {
        _connectionString = connectionString;
    }
    public void DoSomething1() {}
    public void DoSomething2() {}
    public void DoSomething3() {}
}

如何在不使用 ILogger 实例的情况下存档上述配置 谢谢

2 个答案:

答案 0 :(得分:1)

问题是 DI 无法创建 Repository 的实例,因为没有无参数构造函数。 Take a look 在文档中用于注入设置而不是在构造函数中需要一个字符串。将您的连接字符串添加到您的 appsettings.json 文件:

{
  "AppSettings": {
    "ConnectionString": "<connection_string>"        
  }
}

ConfigureServices 中注册您的设置类:

public class AppSettings
{
    public string ConnectionString;
}

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<AppSettings>(Configuration.GetSection(AppSettings));
    ...
}

然后您的 Repository 类构造函数将如下所示:

public Repository(IOptions<PositionOptions> options)
{
    _connectionString = options.Value.ConnectionString;
}

您还需要将接口 IRepository,而不是具体的类注入您的控制器。

public class BaseAPIController
{
    private readonly IRepository _repository;
    public BaseAPIController(IRepository repository)
    {
        _repository = repository;
    }

    // some common functions and properties are declared here
}

答案 1 :(得分:1)

这是您进行的注册:

services.AddScoped<IRepository, Repository>();

但这是 AccountController 的构造函数:

AccountController(Repository repository)

注意 AccountController 如何取决于具体类型 Repository;不在 IRepository 界面上。由于这种注册,Repository 可以只能通过其 IRepository 接口解析,但不能直接解析(这是 MS.DI 的设计)。

因此,解决方案是将 AccountController 的构造函数更改为以下内容:

AccountController(IRepository repository)
相关问题