【问题标题】:Access from class library to appsetting.json in Asp.net-core从类库访问 Asp.net-core 中的 appsetting.json
【发布时间】:2016-07-15 13:59:41
【问题描述】:

我正在尝试从类库访问appsetting.json 文件。到目前为止,我找到的解决方案是从Microsoft.Extensions.Configuration 创建一个实现接口IConfiguration 的配置类,并将json文件添加到类并从中读取。

var configuration = new Configuration();
configuration.AddJsonFile("appsetting.json");
var connectionString= configuration.Get("connectionString");

这似乎是一个不好的选择,因为我们每次必须访问 appsetting 配置时都​​必须添加 json 文件。我们在 ASP.NET 中没有像 ConfigurationManager 这样的替代方案吗?

【问题讨论】:

标签: c# asp.net-core .net-core asp.net-core-mvc


【解决方案1】:

我知道一个答案已经被接受,但这个问题是 Google 上的热门问题,OPs 问题是关于类库而不是 ASP.NET Web 应用程序或 WebApi,这是接受的答案使用的。

IMO,类库不应使用应用程序设置,并且应与此类设置无关。如果您需要类库中的应用程序设置,那么您应该从您的消费者那里提供这些设置。你可以看看这个On This SO Question的例子

【讨论】:

  • 我部分同意;对于在 dotnet 核心解决方案中设置为类库的 测试项目,使用或嵌入 appsettings 是完全可以接受的。在这种情况下,测试项目例如类库是当然是消费者。
  • @Moriarty 是的,但在某些情况下,您可能还有多个环境可以在其中执行您的测试套件。在这种情况下,嵌入式设置将不起作用(例如,您有需要知道的集成测试与 API 对话的环境)。我不认为它总是以一种或另一种方式是正确的,而且总是因情况而异。
  • 当然类库应该使用指向本地数据库实例的连接字符串。而 CI 系统会覆盖该设置以使用另一个实例。恕我直言,这个答案还没有解决方案。它不是关于 asp.net 核心,而是关于 .NET CORE 读取应用程序设置!
  • @StephenPorter 我不同意。在一个高度划分的生态系统中,每个 DLL 都可能利用可配置的特性,主要消费者不知道层中发生了什么。例如,成像组件可以被配置为利用不同的成像提供者。值得庆幸的是,微软将System.Configuration 引入了支持app.config 文件的CORE。这对于那些将项目从框架迁移到核心的人来说尤其重要
  • 我同意@StephenPorter,如果您有一个需要从其他组件中完全抽象出来的数据层,那么在编译代码之外引用连接字符串的方法是必不可少的。
【解决方案2】:

我假设您想从 Web 应用程序访问 appsettings.json 文件,因为默认情况下类库没有 appsettings.json。

我创建了一个模型类,它的属性与appsettings.json 中某个部分的设置相匹配。

appsettings.json 中的部分

"ApplicationSettings": {
    "SmtpHost": "mydomain.smtp.com",
    "EmailRecipients": "me@mydomain.com;other@mydomain.com"
}   

匹配模型类

namespace MyApp.Models
{
    public class AppSettingsModel
    {
        public string SmtpHost { get; set; }
        public string EmailRecipients { get; set; }
    }
}

然后填充该模型类并将其添加到 DI 容器中的 IOptions 集合中(这是在 Startup 类的 Configure() 方法中完成的)。

services.Configure<AppSettingsModel>(Configuration.GetSection("ApplicationSettings"));

// Other configuration stuff

services.AddOptions();

然后,您可以从框架调用的任何方法访问该类,方法是将其添加为构造函数中的参数。框架负责查找类并将其提供给构造函数。

public class MyController: Controller
{
    private IOptions<AppSettingsModel> settings;

    public MyController(IOptions<AppSettingsModel> settings)
    {
        this.settings = settings;
    }
}

然后当类库中的方法需要设置时,我要么单独传递设置,要么传递整个对象。

【讨论】:

  • 不确定自从这被接受为答案后是否发生了变化,但是当我两天前开始一个新项目时它对我不起作用。我为使其正常工作所做的更改是:而不是 IOptions 设置;我必须将其更改为 AppSettingsModel 设置;然后在控制器构造函数中,我更改了这一行 this.settings = settings;到 this.settings = settings.Value;然后它开始工作了。
  • 上面的答案在services.Configure()调用后忘记了Startup下面这行代码:services.AddOptions();
  • @StephenPorter 很乐意在他的回答中添加您的行。
  • 如果你没有在settings 上获得智能,那么在上面的例子中有几件事需要改变。参考这个微软文档:here
  • 原始发帖人询问如何从类库而不是 ASP.Net MVC 控制器访问配置。
【解决方案3】:

除了问题有一个公认的答案之外,我相信没有任何一个问题只适用于一个没有启动项目或与 Asp.NetCore 堆栈或 IServiceCollection 有依赖关系的类库。

这就是我从类库中读取配置的方式:

using Microsoft.Extensions.Configuration;
using System.IO;

public class ConfigSample
{
    public ConfigSample
    {
            IConfigurationBuilder builder = new ConfigurationBuilder();
            builder.AddJsonFile(Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json"));

            var root = builder.Build();
            var sampleConnectionString = root.GetConnectionString("your-connection-string");
    }
}

需要以下 nuget 包:

  • Microsoft.Extensions.Configuration
  • Microsoft.Extensions.Configuration.FileExtensions
  • Microsoft.Extensions.FileProviders.Abstractions
  • Newtonsoft.Json
  • Microsoft.Extensions.Configuration.Json

【讨论】:

    【解决方案4】:

    我知道这个问题有一个可接受的答案,但问题是关于类库的,从类库中读取 appsettings.json 的方法如下:

    创建一个具有与您的设置文件中的属性相匹配的属性的模型:

    public class ConfigurationManager
    {
        public string BaseUrl { get; set; }
    }
    

    在您的 appsettings.json 中添加实际设置

      "ConfigurationManager": {
        "BaseUrl": "myValue"
      }
    

    现在在 startup.cs 中使用您的模型注册 appsettings.json 部分:

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

    在你的类库中创建一个正在使用的类

    using Microsoft.Extensions.Options;
    

    并获取您的配置设置:

    using Microsoft.Extensions.Options;
    
    
    public class KeyUrls: IKeyUrls
    {
        public string BaseUrl = "";
        private readonly IOptions<ConfigurationManager> _configurationService;
    
        public KeyUrls(IOptions<ConfigurationManager> configurationservice)
        {
            _configurationService = configurationservice;
            BaseUrl = _configurationService.Value.BaseUrl;
        }
    
        public  string GetAllKeyTypes()
        {
            return $"{BaseUrl}/something";
        }
    
        public  string GetFilteredKeys()
        {
            return $"{BaseUrl}/something2";
        }
    }
    

    更多详情请查看This

    【讨论】:

    • 问这个问题可能为时已晚,但我认为我有与上述类似的情况。假设您的 KeyUrls 类在另一个项目中,而您的 services.Configure 代码在另一个项目中。如何调用您的 GetAllKeyTypes 方法?如果使用 IKeyUrls obj= new KeyUrls();是你在构造中获得配置值的那个。由于所有明显的原因,我正面临编译时错误。
    【解决方案5】:

    这很容易做到

    string c = Directory.GetCurrentDirectory();
    IConfigurationRoot configuration = 
    newConfigurationBuilder().SetBasePath(c).AddJsonFile("appsettings.json").Build();
    string connectionStringIs = configuration.GetConnectionString("MyConnection"); 
    

    从最后一行可以得到连接字符串

    如果要配置上下文,请额外编写以下代码:

    optionsBuilder.UseSqlServer(connectionStringIs); //inside protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    

    别忘了安装和使用这些包:-

    using Microsoft.Extensions.Configuration; 
    using Microsoft.Extensions.Configuration.FileExtensions; 
    using Newtonsoft.Json; 
    using Microsoft.Extensions.Configuration.Json; 
    using System.IO;
    

    【讨论】:

    • 很好,节省了很多时间
    【解决方案6】:

    在类构造函数 DI 中工作。 微软文档Here

    【讨论】:

    • 欢迎来到 StackOverflow。你能提供更多细节吗?也许是代码 sn-p 和解释?查看帮助中心部分以获取有关回答问题的提示stackoverflow.com/help/answering
    【解决方案7】:
    Directory.SetCurrentDirectory(AppContext.BaseDirectory);
    var builder = new ConfigurationBuilder().SetBasePath (  Path.Combine(Directory.GetCurrentDirectory())   )
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
    

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-28
    • 2019-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-28
    • 2017-09-17
    相关资源
    最近更新 更多