为.Net Core中的静态类提供配置

问题描述 投票:0回答:2

我很好奇可以采取什么方法来解决以下问题。

我在 WPF 应用程序中使用

Properties.Settings.Default
来存储一些配置。我想到应该可以将代码与该变量解耦。所以我想出了这样的方法来启用配置类的 DI:

public partial class App : Application
{
    private ServiceProvider _serviceProvider;

    protected override void OnStartup(StartupEventArgs e)
    {
        //configureSservices and buildServiceProvider
    }

    private void ConfigureServices(IServiceCollection services)
    {
        var configuration = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .Build();
        
        services.AddSingleton<IConfiguration>(configuration);
        services.AddTransient<MainWindow>();
        services.AddTransient<IMainViewModel, MainViewModel>();
        services.AddTransient<IDataService, DataService>();
    }
}

考虑到这段代码,如果我想在其他类中使用配置,我可以这样做:

public class MyClass
{
    private readonly IConfiguration _config;

    public MyClass(IConfiguration config)
    {
        _config = config;
        var mySetting = _config["MySetting"];
    }

    //or even like this...
    public void MyMethod()
    {
        var config = ServiceProvider.GetService<IConfiguration>();
        var mySetting = config["MySetting"];
        // ...
    }
}

我现在的问题是如何在静态类中使用此配置,这些配置已经在太多地方使用了

Properties.Settings.Default
,因为前面的方法都不可能。

我想一种可能的方法是重构所有静态方法,如下所示:

public static class MyStaticClass
{
    public static void MyMethod(IConfiguration config)
    {
        var mySetting = config["MySetting"];
    }
}

这个解决方案有哪些缺点?让它们成为非静态会更好吗(尽管它们只提供实用方法)?

感谢您的阅读!

c# .net-core dependency-injection
2个回答
4
投票

您无法将依赖项注入到静态类中,因为静态类的范围/生命周期独立于主应用程序线程。

当处理器到达在 App 中注册 DI 的代码行时,这些静态类已经在内存中启动。

在寄存器语句和静态类代码上设置一些断点,您将看到静态类在 App.cs 启动之前就已初始化。

解决方案是仅对不需要配置的事物使用静态类 - 实用程序类型函数和具有这种性质的事物,而不是处理应用程序业务逻辑的函数。

问问自己:为什么这些是静态的?您可能没有充分的理由这样做。


0
投票

您可以在该静态类中创建静态方法来获取如下设置

    private static ApplicationSettings GetSiteSettings(IServiceCollection services)
{
    var provider = services.BuildServiceProvider();
    var siteSettingsOptions = provider.GetRequiredService<IOptionsSnapshot<ApplicationSettings>>();
    var siteSettings = siteSettingsOptions.Value;
    if (siteSettings == null) throw new ArgumentNullException(nameof(siteSettings));
    return siteSettings;
}

然后在静态类中调用这个方法

© www.soinside.com 2019 - 2024. All rights reserved.