将 IOptions 传递给 .Net 核心中间件类以进行 json 配置检索
Posted
技术标签:
【中文标题】将 IOptions 传递给 .Net 核心中间件类以进行 json 配置检索【英文标题】:Passing IOptions into .Net core middleware class for json config retrieval 【发布时间】:2017-01-22 06:57:28 【问题描述】:我正在尝试根据 .net 核心中的Options pattern 使用强类型的 json 配置设置。到目前为止的所有示例都显示了将强类型设置类注入控制器是多么容易,但我需要在中间件类中使用它(与this question 非常相似,但在尝试过这种方式后我没有进一步前进)。
所以,设置:
mysettings.json
"MySettings":
"Name": "Some Name from config",
"Description": "Some Description from config"
mysettings.cs
public class MySettings
public string Name get; set; = "Default name";
public string Description get; set; = "Default description";
startup.cs
public void ConfigureServices(IServiceCollection services)
services.AddMvc();
// Add functionality to inject IOptions<T>
services.AddOptions();
// Add our Config object so it can be injected
services.Configure<MySettings>(Configuration.GetSection("MySettings"));
services.AddSingleton<IMySettingsService, MySettingsService>();
MysettingsService.cs
public class MysettingsService : IMysettingsService
private MySettings mySettings get; set;
public MysettingsService (MySettings _mySettings)
mySettings = _mySettings.value;
public string GetName()
return mySettings.Name;
如何实例化 MysettingsService.cs 并将 IOptions<MySettings>
注入到类构造函数中以便调用 GetName 方法?
【问题讨论】:
【参考方案1】:几点:
上述类中缺少构造函数 - MysettingsService 您是否在 Startup 类中注册了 IMysettingsService 的实现? 注册实现时,您可以初始化MysettingsService,如下所示:services.AddSingleton<IMysettingsService, MysettingsService >(i => new MysettingsService ());
按照以下步骤操作:
确保您已在 ConfigurationBuilder 中注册您的 JSON 文件 - mysettings.json定义我的设置
public class MySettings
public string Name get; set;
public string Description get; set;
定义MySettingsService
public class MySettingsService : IMySettingsService
private readonly MySettings mySettings;
public MySettingsService (IOptions<MySettings> _mySettings)
mySettings = _mySettings.Value;
public string GetName()
return mySettings.Name;
在启动中
services.Configure<MySettings>(this.Configuration.GetSection("MySettings"));
services.AddSingleton<IMySettingsService, MySettingsService >();
已编辑——我包含了你要遵循的实现
我创建了一个示例应用程序,它适用于我;请按照以下步骤操作:
细节很少。
我的应用名称是:SettingsApp
-
创建设置文件 -
mySettings.json
- 包含内容
"MySettings": "Name": "Some Name from config", "Description": "Some Description from config"
-
在
Startup
中配置
public Startup(IHostingEnvironment env) var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("mySettings.json", true, reloadOnChange: true) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.env.EnvironmentName.json", optional: true) .AddEnvironmentVariables(); if (env.IsDevelopment()) // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately. builder.AddApplicationInsightsSettings(developerMode: true); Configuration = builder.Build();
见行:
.AddJsonFile("mySettings.json", true, reloadOnChange: true)
-
创建
MySettings
对象以保存设置
namespace SettingsApp.Initialisations public class MySettings public string Name get; set; public string Description get; set;
注意:我使用命名空间SettingsApp.Initialisations
来保存这个文件。您可以根据您的应用程序结构选择任何一种。
-
创建接口
IMySettingsService
namespace SettingsApp.Services public interface IMySettingsService string GetName();
注意:我为此使用命名空间SettingsApp.Services
。
-
实现接口-
IMySettingsService
using SettingsApp.Initialisations; using Microsoft.Extensions.Options; namespace SettingsApp.Services public class MySettingsService : IMySettingsService private readonly MySettings mySettings; public MySettingsService(IOptions<MySettings> _mySettings) mySettings = _mySettings.Value; public string GetName() return mySettings.Name;
-
添加选项并让系统知道您在
Startup.ConfigureServices
方法中的实现
// This method gets called by the run time. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) // Options services.AddOptions(); services.Configure<MySettings>(this.Configuration.GetSection("MySettings")); services.AddSingleton<IMySettingsService, MySettingsService>(); // Add framework services. services.AddApplicationInsightsTelemetry(Configuration); services.AddMvc();
注意包括所需的使用。
查看下面的代码以了解这是如何完成的:
// Options services.AddOptions(); services.Configure<MySettings>(this.Configuration.GetSection("MySettings")); services.AddSingleton<IMySettingsService, MySettingsService>();
-
使用实现(我使用
HomeController
进行测试。)
public class HomeController : Controller private IMySettingsService mySettingsService; public HomeController(IMySettingsService settingsService) mySettingsService = settingsService; public IActionResult Index() // Get the settings var name = mySettingsService.GetName(); return View(); ...
-
查看结果:
【讨论】:
感谢您的帮助,但我已经完成了您提到的所有步骤。如何使用 MySettingsservice 的实例来调用 GetName 方法?特别是,我如何传入一个 IOptions在较新版本的 .NET 中,上述绑定方法不再起作用。
我创建了一个有效的扩展方法:
public static void AddSettings<T>(this IServiceCollection serviceCollection, IConfiguration configuration) where T : class, new()
var settings = new T();
configuration.Bind(typeof(T).Name, settings);
serviceCollection.AddSingleton(settings);
像这样使用它:
services.AddSettings<LoggingSettings>(configuration);
完整示例:
string pathToConfigFile = "c:\\config.json";
IConfiguration configuration = new ConfigurationBuilder()
.AddJsonFile(pathToConfigFile, optional: false, reloadOnChange: true)
.Build();
var services = new ServiceCollection()
services.AddSingleton(configuration);
services.AddSettings<ConnectionSettings>(configuration);
services.AddSettings<LoggingSettings>(configuration);
services.AddSettings<AutoCreateSettings>(configuration);
【讨论】:
以上是关于将 IOptions 传递给 .Net 核心中间件类以进行 json 配置检索的主要内容,如果未能解决你的问题,请参考以下文章
我们可以将 Func<T,TResult> 传递给 .Net core 5 中的中间件来执行吗?