使用 IoC 容器(例如 autofac)来存储应用程序设置是好习惯吗?

Is using IoC container (such as autofac) to store application settings good practice?

之前我曾将连接字符串等设置存储在 settings.json 文件中。创建 类 这样的坏习惯吗?

界面

public interface IConnectionString
{
    string Host { get; set; }
    string Password { get; set; }
    int Port { get; set; }
    string Username { get; set; }


    /// <summary>
    ///     Converts it to a string that DB will understand
    /// </summary>
    string AsString();
}

public class MongoDbLocalConnectionString : IConnectionString
{
    public int Port { get => 27017; set { } }

    public string Host { get => "localhost"; set { } }
    public string Password { get => null; set { } }
    public string Username { get => null; set { } }

    public string AsString()
    {
        if (string.IsNullOrEmpty(Host))
        {
            if (Debugger.IsAttached) { Debugger.Break(); }
            ULoggerDefinitions.Logger.Log(LogType.Error, "HBY5-BT7H", "host cannot be null");
            throw new Exception("98NO-KVKR");
        }

        // connect without authenticating
        if (string.IsNullOrEmpty(Password))
        {
            return $"mongodb://{Host}:{Port}";
        }

        // ... etc
    }
}

// Additional connection strings implementing IConnectionString....
public class DebugConnectionString : IConnectionString {
// ... etc

现在有了 autofac,select 我想使用什么连接字符串就很方便了。我可以做这样的事情:

var builder = new ContainerBuilder();

// register defaults
builder.RegisterType<CoreLogger>().As<ILogger>().SingleInstance();
builder.RegisterType<Foo>().As<IFoo>().SingleInstance();

using (var scope = builder.Build().BeginLifetimeScope((ContainerBuilder b) => {

    // register/override dependencies for this
    b.RegisterType<DebugConnectionString>.As<IConnectionString>();

    // can add more registrations...
}))
{
    // connection string will exist only in this scope
}

有这样的东西而不是 settings.json 文件的坏习惯?

我认为在代码中存储敏感数据是一种糟糕的方式。使用 IConfiguration,您不仅可以使用文件,还可以使用环境变量(部署的最佳方式)或用户机密(如果您不想在 git 存储库中存储一些受保护的数据,则最好的方式)。你也可能想使用 IOptions usage.

此外,您需要根据任何更改重新构建您的项目(反对重新运行)。