3

我创建了一个 .net 核心工作服务,将 IConfiguration 注入其中,这样我就可以从 appsettings.json 读取一个属性,但是每次我运行该文件时,该属性都会显示为空。但是,如果我强制 IConfiguration 通过 ConfigurationBuilder 添加一个 json 文件,它就可以工作。如何使用默认设置来允许 .net core worker 服务从 appsettings 中读取?

public class ImageFileWatcher : IHostedService, IDisposable
{

    private readonly ILogger _logger;
    private readonly IConfiguration _configuration;
    FileSystemWatcher _watcher;

    public ImageFileWatcher(ILogger<ImageFileWatcher> logger, IConfiguration configuration)
    {
        _logger = logger;
        _configuration = configuration;
        // IConfigurationBuilder builder = new ConfigurationBuilder()
        // .AddJsonFile("appsettings.json")
        // .AddEnvironmentVariables();
        // this._configuration = builder.Build();
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {

        var watcherConfig = _configuration["WatcherConfig:filePath"];//this is where it comes up as null.
        _logger.LogInformation($"Image File watcher started on path{watcherConfig}");
        _watcher = new FileSystemWatcher(watcherConfig);
        _watcher.Created += OnNewImage;
        _watcher.EnableRaisingEvents = true;
        return Task.CompletedTask;
    }

这是 appsettings.json 文件

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "WatcherConfig":{

    "filePath":"/Users/###/Documents/Development/ImageDrop"
  }
  
}

这是 Program.cs 文件

public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostContext, configBuilder) =>
                {


                    configBuilder
                    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                    .AddJsonFile("appsettings.Production.json", optional: true, reloadOnChange: true)
                    .AddEnvironmentVariables(prefix: "ImageService_")
                    .Build();

                })
                .ConfigureServices((hostContext, services) =>
                {

                    services.AddHostedService<ImageFileWatcher>();

                });
    }

这是 Program 类的第二次尝试:

public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)

                .ConfigureServices((hostContext, services) =>
                {
                    IConfiguration builder = new ConfigurationBuilder()
                     .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                    .AddJsonFile("appsettings.Production.json", optional: true, reloadOnChange: true)
                    .AddEnvironmentVariables(prefix: "ImageService_")
                    .Build();

                    hostContext.Configuration = builder;
                    services.AddHostedService<ImageFileWatcher>();

                });
    }
4

3 回答 3

2

鉴于您使用的是默认appsettings.json设置,使用CreateDefaultBuilder()应该意味着您无需配置任何额外内容。

有几点可能会有所帮助:

  • 删除任何不需要的自定义配置设置(因为CreateDefaultBuilder

  • 确保将appsettings.json文件复制到构建输出。如果没有,在 Visual Studio 中,您可以右键单击该文件并将“复制到输出目录”设置为“如果较新则复制”。

或者,如果您想手动配置,请注意:

  • 配置主机时,添加您的配置提供程序,您不需要调用该Build()方法。

  • 在您的第二个Program配置示例中,正在设置中ConfigureServices,这不是它应该在的位置。我想这就是为什么必须使用不需要的行的hostContext.Configuration = builder原因。

于 2022-01-09T22:17:13.807 回答
0

在构建主机服务时,您必须阅读 Program.cs 中的应用程序设置。查看 Host.CreateDefaultBuilder 做了什么,如果您决定不使用默认构建器,您可能需要隐式加载设置。

如果您还有其他问题,请附上 Program.cs 文件,因为 IConfiguration 取决于其初始化而不是服务中的使用。

于 2022-01-09T18:05:13.667 回答
0

我也以类似的方法遇到过这个问题。

很高兴“dotnet clean”和“dotnet build”为您工作。

下面,只是想为不同的解决方案做出贡献。

  • appsettings.json上的右键> 属性 > 复制到输出目录 > 始终复制

  • 程序


     static class Program
        {
            public static IConfigurationRoot Configuration { get; private set; }
    
            static async Task Main(string[] args)
            {
                using IHost host = CreateHostBuilder(args).Build();
    
            }
    
            static IHostBuilder CreateHostBuilder(string[] args) =>
              Host.CreateDefaultBuilder(args)
               .ConfigureAppConfiguration((hostingContext, configuration) =>
                {
                    configuration.Sources.Clear();
    
                    configuration
                            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
    
                    IConfigurationRoot configurationRoot = configuration.Build();
    
                    Configuration = configurationRoot;
                }).ConfigureServices((services) =>
                {
                    services.RegisterServices();
                });
        }

  • 创建了一个名为 AppSettings 的类和另一个名为 EndPoint 的类来与appsettings.json数据进行交互

    public class EndPoint
        {
            public string UrlWebApi { get; set; }
         }
    
        public class AppSettings
        {
            public EndPoint EndPoints { get; set; }
    
            public string Application { get; set; }
           
            public AppSettings()
            {
                IConfigurationBuilder builder = new ConfigurationBuilder();
    
                builder.AddJsonFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "appsettings.json"));
    
                var root = builder.Build();
    
                root.Bind(this);
            }
        }

  • 使用 Appsettings 类从 appsettings.json 获取 URL 的示例

    public class MyAppService : IMyAppService
        {
            private readonly AppSettings _appSettings;
            private readonly ILogger<MyAppService> _logger;
    
            public MyAppService(AppSettings appSettings, ILogger<MyAppService> logger)
            {
                _appSettings = appSettings;
                _logger = logger;
            }
    
            public async Task<string> ShowAppSettingsUse()
            {
                    _logger.LogInformation("Getting endpoint URL from AppSettings...");
    
                    var urlFromAppSettings = _appSettings.EndPoints.UrlWebApi;
    
                    return urlFromAppSettings;
            }
        }
    }
于 2022-01-10T15:56:18.290 回答