【问题标题】:How to call services.Configure from Configure method in Startup.cs如何从 Startup.cs 中的 Configure 方法调用 services.Configure
【发布时间】:2020-04-25 23:01:00
【问题描述】:

在我的 Startup.cs 文件中的 ConfigureServices() 中,我称之为

if (services.BuildServiceProvider().GetService<IWebHostEnvironment>().IsDevelopment()) {
 services.Configure<EnvironmentSettings>(Configuration.GetSection("WebServicesDevelopment"));
} else {
 services.Configure<EnvironmentSettings>(Configuration.GetSection("WebServicesProduction"));
}

我收到一个构建警告说

从应用程序代码中调用“BuildServiceProvider”会导致创建一个额外的单例服务副本。考虑将依赖注入服务等替代方案作为“配置”的参数

如何使用 IApplicationBuilder 从 Configure() 调用它?

【问题讨论】:

  • 为什么要移动它?这两种方法用于执行两个单独的任务。您在 ConfigureServices 中配置服务,在 Configure 中配置应用程序管道
  • 因为当我构建时,我收到一条警告说“从应用程序代码调用'BuildServiceProvider'会导致创建一个额外的单例服务副本。考虑将依赖注入服务等替代方案作为“配置”的参数'"
  • 对不起!让我编辑我的帖子以进一步解释。
  • 哦,我想我可以将“IServiceCollection”注入“Configure()”?
  • 不,不要那样做。看我的回答

标签: c# .net-core


【解决方案1】:

首先,检查multiple environments support in ASP.NET Core。您可以配置环境特定部分以避免代码中的if-else 语句。

现在假设上述方法不适合你:

您应避免按照警告消息中所述的原因在ConfigureServices 方法中构建容器。

相反,您应该使用options pattern:

services.AddOptions<EnvironmentSettings>()
    .Configure<IConfiguration, IWebHostEnvironment>(
        (settings, config, env) =>
        {
            if (env.IsDevelopment())
            {
                config.GetSection("WebServicesDevelopment").Bind(settings);
            }
            else
            {
                config.GetSection("WebServicesProduction").Bind(settings);
            }
        });

【讨论】:

    【解决方案2】:

    正如警告所述,调用BuildServiceProvider 可能会产生意想不到的副作用,并且是一种反模式。服务是在ConfigureServices 中配置的,我们拥有所有必要的工具来根据环境执行条件配置。只需在 Startup 类的构造函数中注入 IWebHostEnvironment 并适当地配置您的服务:

    public class Startup
    {
        private readonly IWebHostEnvironment _env;
    
        public Startup(IConfiguration configuration, IWebHostEnvironment env /* take dependency on environment */)
        {
            Configuration = configuration;
            _env = env; // store environment
        }
    
        public IConfiguration Configuration { get; }
    
        public void ConfigureServices(IServiceCollection services)
        {
            // configure based on environment
            if (_env.IsDevelopment())
            { 
                services.Configure<EnvironmentSettings>(Configuration.GetSection("WebServicesDevelopment"));
            } 
            else 
            {
               // non-dev services
               services.Configure<EnvironmentSettings>(Configuration.GetSection("WebServicesProduction"));
            }
        }
    }
    

    请参阅以下文档:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/startup?view=aspnetcore-3.1 搜索短语“只能注入以下服务类型”

    This link 有更多信息,包括如何拥有多个 Startup 类或多个 ConfigureServices 方法(每个环境)

    【讨论】:

    • 嗨粉红色。我认为我必须解决的问题是,在您的 if 语句中,在您检查开发环境的地方,我需要运行此“services.Configure(Configuration.GetSection("WebServicesDevelopment"));”它使用从 appsettings 文件中提取的所有适当数据填充 EnvironmentSettings 对象。我需要弄清楚如何在配置方法中做到这一点。或者相反,确定 ConfigureServices 方法中的 dev/prod 是否可以工作!
    • 不,您不需要在 Configure 中执行此操作。您需要/必须在 ConfigureServices 中执行此操作。我的示例准确显示了如何确定 ConfigureServices 中的 dev/prod 是否存在。我没有关注你的担忧。在上面代码中的“// Dev services”后面加上services.Configure&lt;EnvironmentSettings&gt;(Configuration.GetSection("WebServicesDevelopment")),在else块中添加另一个版本
    猜你喜欢
    • 2015-10-11
    • 1970-01-01
    • 2015-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    • 2016-01-08
    • 1970-01-01
    相关资源
    最近更新 更多