简体   繁体   中英

Accessing appsettings.json from different projects

I am using .Net Core 2.1 to create a Web API. My solution contains different projects and there is one appsettings.json file in the main/startup project. I want to read appsettings from different projects. For that I have created a class in a Common project referenced to every other projects.

namespace Common
{
    public sealed class ApplicationSettings
    {
        public ApplicationSettings(IConfiguration configuration)
        {
            InitSettings(configuration);
        }

        public string CloudStorageConnectionString { get; private set; }

        private void InitSettings(IConfiguration configuration)
        {
            CloudStorageConnectionString = configuration["CloudStorageAccountConnection"];
        }
    }
}

Then I try to configure this in the Startup class in the startup project-

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    //I can read the AppSettings values here via Configuration..

    var settings = new ApplicationSettings(Configuration);
    services.AddSingleton(settings);
}

Finally using it-

public class ToolService : IToolService
{
    private DataContext _dataContext = null;
    private readonly Common.ApplicationSettings _settings;
    public ToolService()
    {
        _dataContext = new DataContext();
    }

    public ToolService(Common.ApplicationSettings settings)
    {
        _settings = settings; //settings is null here
    }

    public ToolDetailModel ReadToolDetail(int toolDetailID)
    {
        ToolDetailModel toolDetailModel = null;
        try
        {
            var cloudConnection = _settings.CloudConnectionString; //settings is null here      
            //...
        }
        catch
        {

        }
        return toolDetailModel;
    }
}

This is how I am calling the above function, again in my API controller which is in the main startup project-

public class ValuesController : ControllerBase
{
    // GET api/values
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        IToolService _toolService = new ToolService();
        _toolService.ReadToolDetail(1);
        //...
        return new string[] { "value1", "value2" };
    }
}

The AppSettings object is null when I am trying to use them in a different project by passing them as parameter (using Dependency Injection as shown above).

Am I doing it wrong? Please let me know if I can add more details.

You have defined two constructors for ToolService and currently you are calling the wrong constructor in your other project. You should modify it so you have only one constructor:

public ToolService(Common.ApplicationSettings settings)
{
    _dataContext = new DataContext();
    _settings = settings; //settings is null here
}

If you want your class library to use dependency injection then you need to register it with the services collection eg

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    //I can read the AppSettings values here via Configuration..

    var settings = new ApplicationSettings(Configuration);
    services.AddSingleton(settings);

    // use whatever lifetime you prefer
    services.AddScoped<ToolService>();
}

Now when you try to call new ToolService() it will complain saying you need to provide the ApplicationSettings parameter. The problem is you cannot use new ToolService() if you are using dependency injection. You need to ask the dependency injector to create the class for you. In the case of ASP.NET Core, that is the IServiceProvider interface.

You don't show where you are creating the ToolService class. If it is in a class that is registered in ConfigureServices then you can just pass the ToolService as a constructor parameter and the dependency injector will resolve the reference for you, including the ApplicationSettings parameter that the ToolService class wants eg

public class MyClass
{
    public MyClass(ToolService toolService)
    {
        _toolService = toolService;
    }

    public void MyMethod()
    {
        _toolService.ReadToolDetail(1);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM