如何从 AppSettings 读取配置值并将配置注入接口实例
Posted
技术标签:
【中文标题】如何从 AppSettings 读取配置值并将配置注入接口实例【英文标题】:How to read configuration values from AppSettings and inject the configuration to instances of interface 【发布时间】:2017-04-19 10:49:07 【问题描述】:就在最近,我一直在尝试新的 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
配置类:
public interface IMyConfiguration
string TerminalId get;set;
bool IsDefault get;set;
public class MyConfiguration : IMyConfiguration
string TerminalId get;set;
bool IsDefault get;set;
然后在我声明的 startup.cs 中,需要通过 MyConfiguration。但我找不到这样做的方法。请指教!
public void ConfigureServices(IServiceCollection services)
services.Configure<MyConfiguration>(Configuration.GetSection("MyConfiguration"));
services.AddSingleton<IProvider>(new ProviderOne(//configuration)); //here is the problem
【问题讨论】:
【参考方案1】:选项 1
首先,你不需要IMyConfiguration
接口。 .NET Core 已经使用自己的 IOptions
接口进行抽象。当你使用
services.Configure<MyConfiguration>(Configuration.GetSection("MyConfiguration"));
你告诉 DI 如何解决下一个依赖:IOptions<MyConfiguration>
所以,而不是
public Provider(IMyConfiguration config)
使用
private MyConfiguration _myConfig;
public Provider(IOptions<MyConfiguration> options)
this._myConfig = options.Value;
ProviderOne
也一样
public ProviderOne(IOptions<MyConfiguration> options) : base(options)
由于 .NET Core DI 知道如何解析已注册的依赖项,现在您可以简单地使用该方法的下一个版本:
services.AddSingleton<IProvider, ProviderOne>();
选项 2
您可以保留您的代码原样;在ConfigureServices
方法中直接实例化MyConfiguration
的实例并用于ypur Provider 实例的创建:
var myConfiguration = new MyConfiguration();
Configuration.GetSection("MyConfiguration").Bind(myConfiguration);
services.AddSingleton<IProvider>(new ProviderOne(myConfiguration));
主要区别在于,在这种情况下,您不会将 DI 容器用于 ProviderOne
实例化。所以主要的缺点是,如果您需要为您的提供者添加更多依赖项(并因此扩展构造函数参数的数量),您也应该在 ConfigureServices
方法中解决这些依赖项。有关更多详细信息,您可能会发现下一个讨论很有用:Best way to resolve during ConfigureServices。
一般来说,当你只有一个IMyConfiguration
的实现时,也可以这样做:
services.AddSingleton<IMyConfiguration>(myConfiguration);
services.AddSingleton<IProvider, ProviderOne>();
DI 容器将了解如何处理它。但是由于内置的 DI 容器不允许注册多个服务然后检索特定的服务,所以这不适合您。有些人通过使用工厂模式来解决这个问题。您将在下一个 SO 问题中找到更多信息:How to register multiple implementations of the same interface in Asp.Net Core?
【讨论】:
很好,但是有一个问题,假设我们有不同的 MyConfiguration 和 Provider 实例,每个提供程序应该如何连接到它的配置。 @Behzad 好的,我添加了选项 2 这样做好吗?我的意思是,我真的很想在我的应用中使用最佳实践 @Behzad 如果简短,请尽可能使用 DI,而不是手动实例化。您的主要问题是您有多个IMyConfiguration
接口的实现,但内置的 ASP.NET Core DI 容器不支持注册多个服务然后检索特定服务。我已经更新了答案,如果你真的有很多不同的 IMyConfiguration
实现,我建议考虑使用一些额外的自己的工厂类进行配置实例化。
@Behzad 你也可以在你的应用程序中使用非默认 IoC,它支持命名依赖项。【参考方案2】:
-
创建一个具有必须从 appsettings 读取的属性的类
Appsettings.json
"DecoderClientOptions":
"url":"someurl@example.com",
"key":"A90474-kGAAP1"
1.创建模型类。
public class DecoderClientOptions
public string url get; set;
public int key get; set;
在 Startup.cs 中注入依赖
services.Configure<DecoderClientOptions>
(Configuration.GetSection(nameof(DecoderClientOptions)));
使用其他类中的属性
public class DecoderClient : IDecoderClient
private readonly IOptions<DecoderClientOptions> _ClientOptions;
public DecoderClient(IOptions<DecoderClientOptions> ClientOptions)
_ClientOptions = ClientOptions;
var url = _ClientOptions.Value.url;
var key = _ClientOptions.Value.key;
【讨论】:
以上是关于如何从 AppSettings 读取配置值并将配置注入接口实例的主要内容,如果未能解决你的问题,请参考以下文章
在 .NET Core 测试项目中读取 appsettings json 值
如何从 appsettings.json 文件中的对象数组中读取值
ASP.NET Core 读取配置 IOptions 控制器未触发