.net核心,n层应用程序,服务层应该依赖于Microsoft.Extensions.Options.dll [英] .net core, n-layered app, should services layer have dependency on Microsoft.Extensions.Options.dll
问题描述
直接的问题是:Microsoft.Extensions.Options.IOptions是否打算仅在伞形应用程序(在这种情况下为Web应用程序)的上下文中或在类库中使用?
Straightforward question is: are Microsoft.Extensions.Options.IOptions meant to be used only within the context of umbrella app (web app in this case) or in class libraries also?
示例:
在n层的asp.net核心应用程序中,我们具有服务层这取决于来自 appsettings.json
文件的某些设置。
In a n-layered, asp.net core app we have services layer that is dependant on some settings coming from appsettings.json
file.
我们首先开始的是这些东西Startup.cs中的行:
What we first started with is something along these lines in Startup.cs:
services.Configure<Services.Options.XOptions>(options =>
{
options.OptionProperty1 = Configuration["OptionXSection:OptionXProperty"];
});
然后在服务构造函数中:
And then in service constructor:
ServiceConstructor(IOptions<XOptions> xOptions){}
假设在我们的服务层中,我们依赖 Microsoft.Extensions.Options
。
But that assumes that in our Service layer we have dependecy on Microsoft.Extensions.Options
.
我们不确定
感觉我们的服务类库应该意识到DI容器的实现有点尴尬。
It just feels a bit awkward our services class library should be aware of DI container implementation.
推荐答案
您也可以注册POCO设置以进行注入,但是会丢失与 appsettings.json $ c时相关的一些功能。 $ c>被编辑。
You can register POCO settings for injection too, but you lose some functionalities related to when the appsettings.json
gets edited.
services.AddTransient<XOptions>(
provider => provider.GetRequiredService<IOptionsSnapshot<XOptions>>().Value);
现在,当在构造函数中注入 XOptions
时,你会上课的。但是,当您编辑 appsettings.json
时,该值将在下一次解决之前更新,这将在下一次请求时针对作用域服务和单例服务永远不会。
Now when you inject XOptions
in constructor, you will get the class. But when your edit your appsettings.json
, the value won't be updated until the next time it's resolved which for scoped services would be on next request and singleton services never.
另一方面注入 IOptionsSnapshot< T>
.Value
始终会为您提供当前设置,即使重新加载 appsettings.json
(假设您已使用 .AddJsonFile( appsettings.json注册, reloadOnSave:true)
)。
On other side injecting IOptionsSnapshot<T>
.Value
will always get you the current settings, even when appsettings.json
is reloaded (assuming you registered it with .AddJsonFile("appsettings.json", reloadOnSave: true)
).
保留该功能但不拉 Microsoft.Extensions.Options的明显原因
包将进入您的服务/域层,将创建您自己的接口和实现。
The obvious reason to keep the functionality w/o pulling Microsoft.Extensions.Options
package into your service/domain layer will be create your own interface and implementation.
// in your shared service/domain assembly
public interface ISettingsSnapshot<T> where T : class
{
T Value { get; }
}
并在应用程序端实现(在服务/域程序集之外) ),即 MyProject.Web
(其中ASP.NET Core和组合根在其中)
and implement it on the application side (outside of your services/domain assemblies), i.e. MyProject.Web
(where ASP.NET Core and the composition root is)
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;
}
并将其注册为
services.AddSingleton(typeof(ISettingsSnapshot<>), typeof(OptionsSnapshotWrapper<T>));
现在您已删除对 IOptions< T> $ c的依赖$ c>和
IOptionsSnapshot< T>
,但保留了它的所有优点,例如在编辑appsettings.json时更新选项。更改DI时,只需将 OptionsSnapshotWrapper< T>
替换为新的实现。
Now you have removed your dependency on IOptions<T>
and IOptionsSnapshot<T>
from your services but retain all up advantages of it like updating options when appsettings.json is edited. When you change DI, just replace OptionsSnapshotWrapper<T>
with your new implementation.
这篇关于.net核心,n层应用程序,服务层应该依赖于Microsoft.Extensions.Options.dll的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!