简体   繁体   English

在.net核心类库中创建静态设置类

[英]Creating a static settings class in .net core class library

I am inviting criticism and feedback. 我邀请批评和反馈。 A roast if you will. 如果愿意的话烤。 What I have done here feels wrong and I want to know why. 我在这里所做的事情感觉不对,我想知道为什么。

To create a static settings class in .net core that can returns settings from the appsettings.json file. 在.net core中创建静态设置类,该类可以从appsettings.json文件返回设置。 It does work but it uses ConfigurationBuilder on every accessing of settings. 它确实可以工作,但是它在每次访问设置时都使用ConfigurationBuilder。

public static class GeneralSettings
{
    private static IConfigurationRoot Configuration = StartConfig();

    private static IConfigurationRoot StartConfig()
    {
        var configBuilder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true)
            .AddEnvironmentVariables();

        return configBuilder.Build();
    }

    public static string ContextUserID
    {
        get
        {
            string result = 
                Configuration.GetSection("AppSettings").GetSection("ContextUserID").Value;

            return result;
        }
    }
}

Given the above code, you're rebuilding the configuration every time its called. 给定以上代码,您将在每次调用配置时重新构建配置。 You may as well make it a singleton. 您也可以将其设为单例。 And since singletons are bad, well something else is probably wrong. 而且由于单身人士不好,所以其他事情可能是错误的。 Your instinct this feels wrong is RIGHT! 您的直觉觉得这是对的!

  1. Avoid static classes until you know they are static. 除非您知道它们是静态的,否则请避免使用static类。
  2. Usually, common 'helper' classes like this violate one or more SOLID principles. 通常,像这样的常见“辅助”类违反了一个或多个SOLID原则。 (This is probably why you have that feel of the code being 'wrong') (这可能就是为什么您觉得代码“错误”的原因)

Read more on how 'helper' classes like this do not adhere to SOLID principles, and what those principles are in this blog article 阅读更多有关此类“辅助”类如何不遵循SOLID原则以及本博客文章中的那些原则的更多信息

If instead of a static class, were you to leverage .NET Core's built in dependency injection, we could easily turn this abstraction into a bit of code that adheres to SOLID principles. 如果不是static类,而是要利用.NET Core的内置依赖项注入,我们可以轻松地将此抽象化为一些符合SOLID原则的代码。 That of course doesn't solve your problem of being able to use your new IContextSettings in another static class, but does enable you to use this interface as a first class citizen directly where you need the ContextUserID , and you would simply use dependency injection in your Controller , or PageModel 当然,这并不能解决您可以在另一个静态类中使用新的IContextSettings问题,但是可以使您直接在需要ContextUserID地方将此接口用作一等公民 ,而您只需在其中使用依赖项注入即可。您的ControllerPageModel

public interface IContextSettings
{
    string ContextUserID { get; }
}

public class ContextSettings : IContextSettings
{
    private IConfiguration configuration;

    public ContextSettings(IConfiguration configuration)
    {
        this.configuration = configuration;
    }
    public string ContextUserID => configuration.GetSection("AppSettings").GetSection("ContextUserID").Value;
}

Usage (RazorPages Example) 用法(RazorPages示例)

public class IndexModel : PageModel
{
    private readonly IContextSettings settings;

    public IndexModel(IContextSettings settings)
    {
        this.settings = settings;
    }
    public IActionResult OnGet()
    {
        var userId = settings.ContextUserID;
        return Page();
    }
}

Feels right... right? 感觉对...对吗?

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

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