首页 > 解决方案 > 依赖注入 IOption 类库

问题描述

我有一个类库,我想从 appsettings.json 访问 Connectionstring。

appsettings.json :

"DatabaseSettings": {
    "ConnectionString": "Server=.;Database=Test;Trusted_Connection=True;"
  },

在 startup.cs 我有以下代码:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<DatabaseSettings>(Configuration.GetSection("DatabaseSettings"));
    services.AddOptions();

    services.AddTransient<IConnectionOption, Class1>();
}

在类库中

IConnectionOption.cs

public interface IConnectionOption
{
    void ReadValue();
}

Class1.cs

public class Class1 : IConnectionOption
{
    private readonly DatabaseSettings test;

    public Class1(IOptions<DatabaseSettings> dbOptions)
    {
        test = dbOptions.Value;    
    }    

    public void ReadValue()
    {
        var r = test;
    }
}

现在从 index.cshtml 我想调用类库 Class1

public class IndexModel : PageModel
{
    public void OnGet()
    {
        Class1 test = new Class1();
        test.ReadValue();
    }
}

但是当然这不起作用,因为没有构造函数采用零参数,我认为我不应该添加 IOptions 作为参数。但是如何调用类库来读取连接字符串呢?(当我让它工作时,我当然会读取数据并返回而不是连接字符串)。我看过几个例子,包括net core 2.1 Dependency injection 但是我不明白如何直接使用类库,是否需要使用控制器?!

标签: c#asp.net-coredependency-injection

解决方案


如果DatabaseSettings类库可以访问,则确实没有太多需要将Class1库与紧密耦合IOptions,这与框架相关。

理想情况下可以通过显式构造函数注入Class1显式依赖DatabaseSettings

public class Class1 : IConnectionOption {
    private readonly DatabaseSettings test;

    public Class1(DatabaseSettings settings) {
        test = settings;    
    }    

    public void ReadValue() {
        var r = test;
        //...
    }
}

然后在 中Startup,可以从配置中提取依赖关系并在 DI 容器中注册

public void ConfigureServices(IServiceCollection services) {
    var settings = Configuration.GetSection("DatabaseSettings").Get<DatabaseSettings>();
    services.AddSingleton<DatabaseSettings>(settings);    
    services.AddTransient<IConnectionOption, Class1>();
}

这样,Class1一旦解决了,容器就会知道如何注入DatabaseSettings依赖项。

另一种选择也可以是使用工厂委托

public void ConfigureServices(IServiceCollection services) {
    var settings = Configuration.GetSection("DatabaseSettings").Get<DatabaseSettings>();
    services.AddTransient<IConnectionOption, Class1>(_ => new Class1(settings));
}

这样,当IndexModel依赖于IConnectionOption注入时。

public class IndexModel : PageModel {
    private readonly IConnectionOption connectionOption;

    public IndexModel(IConnectionOption iConnectionOption) {
        connectionOption = iConnectionOption;
    }

    public void OnGet() {
        connectionOption.ReadValue();
        //...
    }
}

初始化页面模型时将注入正确的依赖项。


推荐阅读