Just recently, I have been trying out the new asp.net features and came across this issue. I know that we can read the configuration as strongly typed instance. but i have no idea how can i inject the configuration to my class in Microsoft dependency injection.
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
}
}
configuration class:
public interface IMyConfiguration
{
string TerminalId { get;set; }
bool IsDefault {get;set;}
}
public class MyConfiguration : IMyConfiguration
{
string TerminalId { get;set; }
bool IsDefault {get;set;}
}
and then in startup.cs as i declared, it is required to pass the MyConfiguration. but i could not find a way to do so. please advice!
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyConfiguration>(Configuration.GetSection("MyConfiguration"));
services.AddSingleton<IProvider>(new ProviderOne(//configuration)); //here is the problem
}
Option 1
First of all, you don't need IMyConfiguration
interface. .NET Core already uses own IOptions
interface for abstraction. When you use
services.Configure<MyConfiguration>(Configuration.GetSection("MyConfiguration"));
you tell the DI how to resolve next dependency: IOptions<MyConfiguration>
So, instead of
public Provider(IMyConfiguration config)
use
private MyConfiguration _myConfig;
public Provider(IOptions<MyConfiguration> options)
{
this._myConfig = options.Value;
}
The same for ProviderOne
public ProviderOne(IOptions<MyConfiguration> options) : base(options)
As .NET Core DI knows how to resolve dependencies that are registered, now you can simply use next version of the method:
services.AddSingleton<IProvider, ProviderOne>();
Option 2
You may leave your code as is; directly instantiate instance of MyConfiguration
in ConfigureServices
method and use for ypur Provider instance creation:
var myConfiguration = new MyConfiguration();
Configuration.GetSection("MyConfiguration").Bind(myConfiguration);
services.AddSingleton<IProvider>(new ProviderOne(myConfiguration));
The main difference is that in this case, you don't use the DI container for ProviderOne
instantiation. And so the main disadvantage is that if you need to add more dependencies for your provider (and so extend number of constructor parameters) you should resolve those dependencies in ConfigureServices
method as well. For more details, you may find next discussion useful: Best way to resolve during ConfigureServices.
In general, for situation when you have only one implementation of IMyConfiguration
, it is possible to do even so:
services.AddSingleton<IMyConfiguration>(myConfiguration);
services.AddSingleton<IProvider, ProviderOne>();
and DI container will understand how to handle that. But as built-in DI container does not allow registering multiple services and then retrieving a specific one, this is not works for you. Some people solve that problem by using the Factory pattern. You will find more in next SO question: How to register multiple implementations of the same interface in Asp.Net Core?
Appsettings.json
{
"DecoderClientOptions":
{
"url":"[email protected]",
"key":"A90474-kGAAP1"
}
}
1.Create a model class.
public class DecoderClientOptions
{
public string url { get; set; }
public int key { get; set; }
}
Inject dependency in Startup.cs
services.Configure<DecoderClientOptions>
(Configuration.GetSection(nameof(DecoderClientOptions)));
Use the properties in other classes
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With