dee*_* zg 4 configuration .net-core asp.net-core
直截了当的问题是:Microsoft.Extensions.Options.IOptions是否只能在伞形应用程序(在本例中为Web应用程序)或类库中使用?
例:
在一个n层的asp.net核心应用程序中,我们的服务层依赖于来自appsettings.json文件的一些设置.
我们刚开始的是Startup.cs中的这些内容:
services.Configure<Services.Options.XOptions>(options =>
{
options.OptionProperty1 = Configuration["OptionXSection:OptionXProperty"];
});
Run Code Online (Sandbox Code Playgroud)
然后在服务构造函数中:
ServiceConstructor(IOptions<XOptions> xOptions){}
Run Code Online (Sandbox Code Playgroud)
但这假设在我们的服务层中我们依赖Microsoft.Extensions.Options.
我们不确定这是推荐的还是有更好的做法?
我们的服务类库应该知道DI容器实现,这感觉有点尴尬.
您也可以注册POCO设置以进行注射,但是您会丢失与appsettings.json编辑时相关的一些功能.
services.AddTransient<XOptions>(
provider => provider.GetRequiredService<IOptionsSnapshot<XOptions>>().Value);
Run Code Online (Sandbox Code Playgroud)
现在,当您注入XOptions构造函数时,您将获得该类.但是,当你编辑你的appsettings.json,该值将不会被直到下一次更新,它解决了这对范围的服务将是对未来的要求和辛格尔顿服务永远.
另一方面,注入IOptionsSnapshot<T> .Value将始终为您提供当前设置,即使appsettings.json重新加载(假设您已注册.AddJsonFile("appsettings.json", reloadOnSave: true)).
保持功能不将Microsoft.Extensions.Options包拉入服务/域层的明显原因是创建自己的接口和实现.
// in your shared service/domain assembly
public interface ISettingsSnapshot<T> where T : class
{
T Value { get; }
}
Run Code Online (Sandbox Code Playgroud)
并在应用程序端(服务/域程序集之外)实现它,即MyProject.Web(ASP.NET核心和组合根目录)
public class OptionsSnapshotWrapper<T> : ISettingsSnapshot<T>
{
private readonly IOptionsSnapshot<T> snapshot;
public OptionsSnapshotWrapper(IOptionsSnapshot<T> snapshot)
{
this.snapshot = snapshot ?? throw new ArgumentNullException(nameof(snapshot));
}
public T Value => snapshot.Value;
}
Run Code Online (Sandbox Code Playgroud)
并将其注册为
services.AddSingleton(typeof(ISettingsSnapshot<>), typeof(OptionsSnapshotWrapper<T>));
Run Code Online (Sandbox Code Playgroud)
现在你已经取消了对你的依赖IOptions<T>,并IOptionsSnapshot<T>从你的服务,但保留了所有的优点,它像appsettings.json编辑时更新选项.更改DI时,只需更换OptionsSnapshotWrapper<T>新实现即可.
| 归档时间: |
|
| 查看次数: |
383 次 |
| 最近记录: |