.net核心,n层应用程序,服务层应该依赖于Microsoft.Extensions.Options.dll [英] .net core, n-layered app, should services layer have dependency on Microsoft.Extensions.Options.dll

查看:122
本文介绍了.net核心,n层应用程序,服务层应该依赖于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 被编辑。

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> 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆