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)
选项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中注册同一接口的多个实现?