How to read config values ​​from AppSettings and inject config into interface instances

I recently tested new asp.net features and faced this issue. I know that we can read the config as a strongly typed instance. but I have no idea how I can add my class configuration 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
    }
}

      

config 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 needs to pass MyConfiguration. but I couldn't find a way to do it. please advice!

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

      

+3


source to share


1 answer


Option 1

First of all, you don't need an interface IMyConfiguration

.. NET Core already uses its own IOptions

interface for abstraction. When you use

services.Configure<MyConfiguration>(Configuration.GetSection("MyConfiguration"));

      

you are telling DI how to resolve the following 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)

      




Since .NET Core DI knows how to resolve registered dependencies, you can now simply use the following version of the method:

services.AddSingleton<IProvider, ProviderOne>();

      




Option 2

You can leave your code as it is; directly instantiate MyConfiguration

in ConfigureServices

and use to instantiate ypur instance:

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

services.AddSingleton<IProvider>(new ProviderOne(myConfiguration));

      

The main difference is that in this case you are not using a DI container to create ProviderOne

. And so the main drawback is that if you need to add more dependencies for your provider (and therefore expand the number of constructor parameters), you must also resolve those dependencies in the method ConfigureServices

. For more details, you may find the following discussion helpful: Best way to resolve during ConfigureServices .

In general, for a situation where you have only one implementation IMyConfiguration

, you can do this:

services.AddSingleton<IMyConfiguration>(myConfiguration);
services.AddSingleton<IProvider, ProviderOne>();

      

and the DI container will figure out how to handle it. But since the built-in DI container doesn't allow you to register multiple services and then retrieve a specific one, this doesn't work for you. Some people solve this problem using the Factory pattern. You will find the following SO question: How do I register multiple implementations of the same interface in Asp.Net Core?

+4


source







All Articles