从类库访问 Asp.net-core 中的 appsetting.json

Posted

技术标签:

【中文标题】从类库访问 Asp.net-core 中的 appsetting.json【英文标题】:Access from class library to appsetting.json in Asp.net-core 【发布时间】: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 这样的替代方案吗?

【问题讨论】:

Using IConfiguration in C# Class Library的可能重复 和Using IConfiguration in C# Class Library是同一个问题,见my answer 对于那些只是想从Framework迁移到CORE的人,这个更适合***.com/a/56498687/1704458 【参考方案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

【讨论】:

欢迎来到 ***。你能提供更多细节吗?也许是代码 sn-p 和解释?查看帮助中心部分以获取有关回答问题的提示***.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。

以上是关于从类库访问 Asp.net-core 中的 appsetting.json的主要内容,如果未能解决你的问题,请参考以下文章

无法从类库访问 appsettings.json

从类库调用 WCF 服务:App.Config 与 Web.Config?

从类库访问用户上下文

获取 ASP.NET-Core 2.2 控制器中的控制器名称和方法名称

ASP.Net-Core 中的自定义身份验证

从类库中访问文件