如何正确解析在 ASP.NET Core 3.1 中的ConfigureServices() 中使用的服务?

2024-01-23

我有一个基于 ASP.NET Core 3.1 的应用程序。在应用程序启动期间,在ConfigureServices(IServiceCollection services)我想注册我的服务。但在配置服务期间,我想根据数据库中找到的设置启动应用程序。

这是我的代码

public void ConfigureServices(IServiceCollection services)
{
    // Register context
    services.AddDbContext<AppDbContext>(options =>
    {
        options.UseMySql(Configuration.GetConnectionString("MySqlServerConnection"));
    });

    // Reister the setting provider
    services.AddSingleton<IAppSetting, AppSettings>();

    // Create a resolver which is WRONG!!
    var resolver = services.BuildServiceProvider();

    var setting = resolver.GetService<IAppSetting>();

    List<string> allowedCors = new List<string>()
    {
         setting.MainUrl.ToString()
    };

    if (setting.HasCustomAssetsUri)
    {
        allowedCors.Add(settings.AssetsUrl.ToString());
    }

    if (settings.HasCustomPhotosUri)
    {
        allowedCors.Add(settings.PhotosUrl.ToString());
    }

    services.AddCors(options =>
    {
        options.AddPolicy("AllowSubDomainTraffic",
        builder =>
        {
            builder.WithOrigins(allowedCors.ToArray())
                   .AllowAnyHeader()
                   .AllowAnyMethod();
        });
    });

    // More services
}

正如您在上面的代码中看到的,我注册了IAppSetting但我立即想用来访问数据库,以便获取当前配置。我目前正在打电话services.BuildServiceProvider()创建一个新的解析器,然后我可以使用它来创建一个实例IAppSetting.

My AppSetting实施取决于AppDbContext这也已注册。这是我的应用程序设置

public class AppSetting : IAppSetting
{
    private AppDbContext context;

    public AppSetting(AppDbContext context)
    {
        this.context = context;
    }

    // methods...
}

Calling BuildServiceProvider()将导致创建单例服务的附加副本。所以我试图避免这样做。

如何正确注册然后解决IAppSetting in the ConfigureServices()方法,以便我可以使用它来访问数据库中找到的设置?

Updated

我尝试使用 Nkosi 提出的解决方案,但出现以下错误

System.InvalidOperationException:“无法解析范围服务 来自根提供商的“IAppSetting”。

这是完整的堆栈跟踪。

This exception was originally thrown at this call stack:
    Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(System.Type, Microsoft.Extensions.DependencyInjection.IServiceScope, Microsoft.Extensions.DependencyInjection.IServiceScope)
    Microsoft.Extensions.DependencyInjection.ServiceProvider.Microsoft.Extensions.DependencyInjection.ServiceLookup.IServiceProviderEngineCallback.OnResolve(System.Type, Microsoft.Extensions.DependencyInjection.IServiceScope)
    Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(System.Type, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope)
    Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(System.Type)
    Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(System.IServiceProvider, System.Type)
    Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(Microsoft.Extensions.DependencyInjection.ServiceLookup.FactoryCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext)
    Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext)
    ...
    [Call Stack Truncated]

参考使用 DI 服务配置选项 https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-3.0#use-di-services-to-configure-options

使用 DI 配置 CORS 选项,将所有逻辑移至配置委托中

//...

// Register context
services.AddDbContext<AppDbContext>(options => {
    options.UseMySql(Configuration.GetConnectionString("MySqlServerConnection"));
});

// Reister the setting provider
services.AddScoped<IAppSetting, AppSettings>(); 

//configure CORS options using DI
services.AddOptions<CorsOptions>()
    .Configure<IServiceScopeFactory>((options, sp) => {
        using(var scope = sp.CreateScope()) {
            IAppSetting settings = scope.ServiceProvider.GetRequiredService<IAppSetting>();
            List<string> allowedCors = new List<string>() {
                 setting.MainUrl.ToString()
            };

            if (setting.HasCustomAssetsUri) {
                allowedCors.Add(settings.AssetsUrl.ToString());
            }

            if (settings.HasCustomPhotosUri) {
                allowedCors.Add(settings.PhotosUrl.ToString());
            }
            options.AddPolicy("AllowSubDomainTraffic", builder => {
                builder.WithOrigins(allowedCors.ToArray())
                       .AllowAnyHeader()
                       .AllowAnyMethod();
            });
        }
    });

services.AddCors();

//...

这样,所有事情现在都会推迟到实际需要的时候,并且您可以避免过早构建服务集合。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何正确解析在 ASP.NET Core 3.1 中的ConfigureServices() 中使用的服务? 的相关文章

随机推荐

  • 为在线商店生成订单号的最佳方法?

    我的在线商店中的每个订单都有一个面向用户的订单号 我想知道生成它们的最佳方法 标准包括 Short 通过电话很容易说出来 例如 m 和 n 是不明确的 Unique 校验和 矫枉过正 有用吗 Edit 不会透露订单总数 客户可能会因为下第三
  • 如何在 xcode 上禁用静态库的链接器警告?

    在我当前的 Swift 项目中 我有一个第 3 方静态库 是通过 构建阶段 gt 链接二进制文件与库 部分添加的 更新到 xcode 8 3 后 该库开始抛出一些链接器警告 例如 指针未在 libraryFile a 的地址 0x00000
  • 在 JavaScript 中从对象创建 DOM 元素

    嗨 我试图了解如何制作 Dom elemnt 比如说 div 形成我的数据对象 我做了一个这样的对象 var div style width Math floor Math random 100 height Math floor Math
  • 使用 Fluent NHibernate 和 guid id

    我们正在使用 Fluent NHibernate 1 2 我们的主键是保存在nvarchar 32 专栏 使用 Oracle 11gr2 我们怎样才能做到这一点 进行自动转换 谢谢 随机程序员 更新 忘了提及 保存的 guid 没有破折号
  • 启动 Facebook 转换像素

    我对 Javascript 还很陌生 但我想知道在不实际加载 确认 谢谢 页面的情况下触发 Facebook 转换像素 如下 的最佳方法是什么
  • Android 本地服务器套接字

    在android中 有两个类LocalServerSocket和LocalSocket 我认为它们类似于unix套接字中的AF LOCAL 我不确定它是否正确 我的问题是 是否可以在Java中创建LocalServerSocket并使用普通
  • Unity 在使用 Firebase 数据库进行异步编程时崩溃

    当我尝试这样做时它崩溃了 我想要异步获取用户数据 如果我不使用异步任务 它会返回 null public class Database MonoBehaviour private DatabaseReference m database p
  • Vue.js 中的计算属性未使用 navigator.onLine 更新

    我想使用 Vue js 计算属性来查看我的应用程序的在线状态 基本上 我有以下 Vue 设置 new Vue el app computed onLine function return navigator onLine 以及以下标记 di
  • 安装后如何更改应用程序的图标和标签?

    我正在尝试在安装应用程序后更改其图标和标签 在清单中 我放置了以下代码
  • UTF-8 的多字节安全 wordwrap() 函数

    PHP s wordwrap https www php net wordwrap对于 UTF 8 等多字节字符串 该函数无法正常工作 评论中有一些mb安全函数的例子 但是根据一些不同的测试数据 它们似乎都存在一些问题 该函数应采用与以下完
  • Ionic Android 构建停止工作

    更新 Ionic 和 Cordova CLI 后 我的 Ionic Cordova 应用程序突然停止在 Android 上构建 过去两天我在谷歌上搜索解决方案 但找不到任何有帮助的东西 我假设这与 Cordova 现在使用 Gradle 来
  • 根据字段的值使用不同的 Pydantic 模型

    我有 2 个 Pydantic 模型 var1 and var2 输入的PostExample方法可以接收第一个模型或第二个模型的数据 指某东西的用途Union有助于解决这个问题 但在验证过程中 它会引发第一个和第二个模型的错误 如何做到在
  • 计算减法后剩余多边形的算法

    我有一个大多边形 Pa 多边形内部有很多小 洞 如图 以下是开孔的几个条件 孔不能互相重叠 孔不能超出外多边形 然而 这些洞can触摸多边形的外边 如何高效地获取剩余的多边形 或多边形列表 最简单的方法 蛮力方法 是采取Pa 并通过减去孔逐
  • json.Unmarshal 不返回解码数据[重复]

    这个问题在这里已经有答案了 我在解组从 a 读取的 json 数据时遇到问题 json file type redisConfig struct host string password string func loadRedisConfi
  • 我可以为主键设置ignore_dup_key吗?

    我的表上有一个两列主键 我试图改变它来设置ignore dup key继续使用此命令 ALTER INDEX PK mypk on MyTable SET IGNORE DUP KEY ON 但我收到这个错误 Cannot use inde
  • 循环依赖最佳实践

    我目前正在编写一个网络爬虫 它从互联网上检索信息 简化后看起来像这样 数据访问项目 检索原始数据的对象 将原始数据解析为对象的对象 解析器返回的实体 现在 我正在创建实际的解析器 我将像这样使用它 using Application Dat
  • 为什么我在 Android 设备上无法接收来自 GCM 的消息

    我正在创建一个 android 应用程序 我需要在其中发送 gcm 消息 到目前为止我设法得到设备ID并将其发送到我的服务器 现在 当我尝试将消息从服 务器推送到我的应用程序时 我收到以下消息 multicast id 4987023356
  • EXC_BAD_ACCESS,代码 1,iOS 7.0.x 64 位设备

    我目前正在开发的应用程序在模拟器上完美运行 但自从 Xcode 升级到 5 1 后 我在设备上运行应用程序时遇到问题 如果我在任何 iOS 上的任何非 64 位设备上运行应用程序 它都可以正常运行 但如果我在 64 位设备 iPhone 5
  • 硒页面对象。如何从外部源读取@FindBy定位器?

    我只能在页面对象 FindBy 注释中使用硬编码值 但我想动态解析定位器 public class LoginPage extends BasePage hardocded value works ok FindBy name login
  • 如何正确解析在 ASP.NET Core 3.1 中的ConfigureServices() 中使用的服务?

    我有一个基于 ASP NET Core 3 1 的应用程序 在应用程序启动期间 在ConfigureServices IServiceCollection services 我想注册我的服务 但在配置服务期间 我想根据数据库中找到的设置启动