从不同的项目访问appsettings.json

时间:2018-07-02 13:46:25

标签: c# asp.net-core asp.net-core-2.0 asp.net-core-webapi

我正在使用.Net Core 2.1创建Web API。我的解决方案包含不同的项目,并且在主/启动项目中有一个appsettings.json文件。 我想阅读来自不同项目的appsettings。为此,我在Common项目中创建了一个引用其他项目的类。

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"];
        }
    }
}

然后我尝试在启动项目的Startup类中进行配置-

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);
}

最后使用它-

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;
    }
}

这就是我在主启动项目中的API控制器中再次调用上述函数的方式-

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" };
    }
}

当我尝试通过将它们作为参数传递给另一个项目(如上所示,使用依赖注入)时,AppSettings对象为null。

我做错了吗?如果可以添加更多详细信息,请告诉我。

1 个答案:

答案 0 :(得分:3)

您为ToolService定义了两个构造函数,当前您在其他项目中调用了错误的构造函数。您应该对其进行修改,以便只有一个构造函数:

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

如果您希望您的类库使用依赖项注入,则需要在services集合中进行注册,例如

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>();
}

现在,当您尝试调用new ToolService()时,会抱怨说您需要提供ApplicationSettings参数。 问题是如果使用依赖项注入,则不能使用new ToolService()。您需要让依赖注入器为您创建类。如果使用ASP.NET Core,则为IServiceProvider接口。

您不会显示正在创建ToolService类的位置。如果它是在ConfigureServices中注册的类中,那么您可以将ToolService作为构造函数参数传递,并且依赖项注入器将为您解析引用,包括ApplicationSettings参数ToolService类想要例如

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

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