如何从AppSettings中读取配置值并将配置注入接口实例

Beh*_*zad 4 c# dependency-injection .net-core asp.net-core

就在最近,我一直在尝试新的asp.net功能并遇到了这个问题。我知道我们可以将配置读取为强类型实例。但是我不知道如何在Microsoft依赖项注入中将配置注入到类中。

public interface IProvider
{
  IMyConfiguration Configuration {get;}
  Task Connect();
}

public abstract class Provider: IProvider
{
    private IMyConfiguration _myConfig;

    public Provider(IMyConfiguration config)
    {
        this._myConfig= config;
    }

    public IMyConfiguration Configuration => _myConfig;
    public abstract Task Connect();
}

public class ProviderOne:Provider
{
    public ProviderOne(IMyConfiguration  config) : base(config)
    {
    }

    public Task Connect()
    {
      //implementation
    }
}
Run Code Online (Sandbox Code Playgroud)

配置类:

public interface IMyConfiguration
{
     string TerminalId { get;set; }
     bool IsDefault {get;set;}
}
public class MyConfiguration : IMyConfiguration
{
     string TerminalId { get;set; }
     bool IsDefault {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

然后在我声明的startup.cs中,需要通过MyConfiguration。但是我找不到办法。请指教!

public void ConfigureServices(IServiceCollection services)
{
  services.Configure<MyConfiguration>(Configuration.GetSection("MyConfiguration"));
  services.AddSingleton<IProvider>(new ProviderOne(//configuration)); //here is the problem
}
Run Code Online (Sandbox Code Playgroud)

Set*_*Set 6

选项1

首先,您不需要IMyConfiguration界面。.NET Core已使用自己的IOptions接口进行抽象。使用时

services.Configure<MyConfiguration>(Configuration.GetSection("MyConfiguration"));
Run Code Online (Sandbox Code Playgroud)

您告诉DI如何解决下一个依赖关系: IOptions<MyConfiguration>

所以,代替

public Provider(IMyConfiguration config)
Run Code Online (Sandbox Code Playgroud)

使用

private MyConfiguration _myConfig;

public Provider(IOptions<MyConfiguration> options)
{
    this._myConfig = options.Value;
}
Run Code Online (Sandbox Code Playgroud)

一样 ProviderOne

public ProviderOne(IOptions<MyConfiguration> options) : base(options)
Run Code Online (Sandbox Code Playgroud)

由于.NET Core DI知道如何解决已注册的依赖关系,因此现在您可以简单地使用该方法的下一个版本:

services.AddSingleton<IProvider, ProviderOne>();
Run Code Online (Sandbox Code Playgroud)

选项2

您可以按原样保留您的代码;直接实例化MyConfigurationin ConfigureServices方法的实例,并用于ypur Provider实例创建:

var myConfiguration = new MyConfiguration();
Configuration.GetSection("MyConfiguration").Bind(myConfiguration);

services.AddSingleton<IProvider>(new ProviderOne(myConfiguration));
Run Code Online (Sandbox Code Playgroud)

主要区别在于,在这种情况下,您不使用DI容器进行ProviderOne实例化。因此,主要的缺点是,如果您需要为提供者添加更多的依赖关系(并因此扩展构造函数参数的数量),则也应该在ConfigureServices方法中解决这些依赖关系 。有关更多详细信息,您可能会发现以下讨论很有用:在ConfigureServices期间解决的最佳方法

通常,对于只有的一种实现的情况IMyConfiguration,甚至可以这样做:

services.AddSingleton<IMyConfiguration>(myConfiguration);
services.AddSingleton<IProvider, ProviderOne>();
Run Code Online (Sandbox Code Playgroud)

DI容器将了解如何处理。但是,由于内置的​​DI容器不允许注册多个服务然后检索特定的服务,因此这不适用于您。有人通过使用Factory模式解决了该问题。您将在下一个SO问题中找到更多信息:如何在Asp.Net Core中注册同一接口的多个实现?