繁体   English   中英

在多租户应用程序中使用数据库中的 IOptions 和加载选项

[英]Using IOptions and load options from database with multi tenant application

我将应用程序移动到 .net 核心并尝试使用 IOptions 模式。

我的应用程序是具有单个数据库的多租户。 系统具有全局默认选项,我将它们保存在数据库中(与我的旧应用程序相同),并且每个租户都有自己的选项。 如果租户没有全局键的选项,那么我需要使用全局选项。

在配置中,我处理从数据库中获取全局选项。 文档中的示例很容易。

然而,每个租户的选择并不顺利。 虽然我实际上知道我想要什么,但我不知道如何在 .Net Core 中做到这一点。

我在控制台应用程序中进行测试。

class Program {
    static void Main(string[] args) {
        var services = ConfigureServices();

        var serviceProvider = services.BuildServiceProvider();

        serviceProvider.GetService<App>().Run();
    }

public class App {
    private readonly IOptionsSnapshot<DemoOptions> _options;

    public App(IOptionsSnapshot<DemoOptions> options) {
        _options = options;
    }

    public void Run() {
        Console.WriteLine("Hello from App.cs");
        Console.WriteLine($"DemoOptions:Global:Enabled={_options.Value.Enabled}");
        Console.WriteLine($"DemoOptions:Global:AutoRetryDelay={_options.Value.AutoRetryDelay}");
        Console.WriteLine($"DemoOptions:Global:IdentityOptions:MaxUserNameLength={_options.Value.IdentityOptions.MaxUserNameLength}");
    }
}

    private static IServiceCollection ConfigureServices() {
        IServiceCollection services = new ServiceCollection();

        //Load global configuration from database and use them.
        var config = LoadConfiguration();
        services.AddSingleton(config);
        
        services.AddDbContext<EntityConfigurationContext>(options => options.UseInMemoryDatabase("InMemoryDb"));
        services.AddScoped<ITenantService, TenantService>();

        
        //I take this part from example link in below. But I am not successed.
        services.AddSingleton<IOptionsMonitorCache<DemoOptions>,TenantOptionsCache<DemoOptions>>();
        services.AddTransient<IOptionsFactory<DemoOptions>,TenantOptionsFactory<DemoOptions>>();
        services.AddScoped<IOptionsSnapshot<DemoOptions>,TenantOptions<DemoOptions>>();
        services.AddSingleton<IOptions<DemoOptions>,TenantOptions<DemoOptions>>();


        // required to run the application
        services.AddTransient<App>();

        return services;
    }

    public static IConfiguration LoadConfiguration() {
        var builder = new ConfigurationBuilder();
        builder.Sources.Clear();

        builder.AddEntityConfiguration(options => options.UseInMemoryDatabase("InMemoryDb"));

        IConfigurationRoot configurationRoot = builder.Build();
        DemoOptions options = new();
        configurationRoot.GetSection($"{nameof(DemoOptions)}:{DemoOptions.Global}").Bind(options);

        Console.WriteLine($"DemoOptions:Global:Enabled={options.Enabled}");
        Console.WriteLine($"DemoOptions:Global:AutoRetryDelay={options.AutoRetryDelay}");
        Console.WriteLine($"DemoOptions:Global:IdentityOptions:MaxUserNameLength={options.IdentityOptions.MaxUserNameLength}");

        return builder.Build();
    }
}

public record DemoOptions {
    public const string Global = nameof(Global);
    public const string Tenant = nameof(Tenant);

    public bool Enabled { get; set; }
    public TimeSpan AutoRetryDelay { get; set; }
    public IdentityOptions IdentityOptions { get; set; }
}

public record IdentityOptions {
    public int MaxUserNameLength { get; set; }
}

public record DemoSettings(string Key, string Value) {
    public int Id { get; set; }
}

public record TenantSettings(string Key, string Value, int TenantId) {
    public int Id { get; set; }
}

我在这里添加了一些重要的 class。 但是,如果您想查看所有项目,我添加github 链接 我用这个例子

我懂了。 你应该做这些事情

  1. 安装 nuget package

Microsoft.Extensions.Options.ConfigurationExtensions

  1. 在 ConfigureServices 中的 Programs.cs 中替换此代码
    var config = LoadConfiguration();
    services.Configure<DemoOptions>(config.GetSection($"{nameof(DemoOptions)}:{DemoOptions.Global}"));
    services.AddSingleton(config);

您可以尝试现成的JsonRepositoryConfiguration Nuget package。 它还具有自动刷新功能,其工作方式与 JSON 配置文件的配置形式非常相似,只是它需要来自您的存储库的 JSON 配置,这反过来可以从任何内部/外部存储中获取数据,包括进行数据库调用,ZDB974238708CA 等.

您可以混合使用不同的配置提供(例如这个和 JSON 配置文件)并根据需要一起使用它们。 忏悔:我是作者。

下一步将使用Named Options

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM