在 .NET 应用程序中注入配置对象

Injecting configuration objects in a .NET application

我正在审查我以前写的代码,我注意到我过去做过

  public class Linq2DbSettings : ILinqToDBSettings
{
    public IEnumerable<IDataProviderSettings> DataProviders
    {
        get { yield break; }
    }

    public string DefaultConfiguration =>
        "SqlServer"; // lets set your configuration as default, so you can call just new DataContext() or new DataConnection()

    public string DefaultDataProvider => ProviderName.SqlServer; // and set default database type


    public IEnumerable<IConnectionStringSettings> ConnectionStrings
    {
        get
        {
            yield return
                new ConnectionStringSettings
                {
                    Name = "SqlServer",
                    ProviderName = "SqlServer",
                    ConnectionString =ConfigurationManager.ConnectionStrings["default"].ConnectionString
                };
        }
    }
}

public class ConnectionStringSettings : IConnectionStringSettings
{
    public string ConnectionString { get; set; }
    public string Name { get; set; }
    public string ProviderName { get; set; }
    public bool IsGlobal => false;
}

即使它与 Linq2Db 相关,它也适用于所有 类 我需要解析容器的地方。

如您所见,我在这里使用 ConfigurationManager.ConnectionStrings["default"],而最好使用 Microsoft.Extensions.Configuration

中的 IConfiuration

为此,我应该解决在 SimpleInjector 的容器中注册的 IConfiguration 项。

以前我用的是wrapper

public static class ContainerWrapper
{
    public static Container Container { get; set; }
}

我将其指定为

    ContainerWrapper.Container = container;

    container.Verify();

但我认为这是一种错误的做法,最好的解决方案是什么?

我的建议如下:

  • 缩小配置对象范围;不要创建包含大量属性并被许多消费者使用的宽配置对象。
  • 防止配置对象从配置系统中读取。使它们成为不可变的无行为数据对象,并在它们的构造函数中为它们提供配置值。这可以防止配置对象成为易失性依赖项。
  • 删除配置对象上的接口。接口旨在隐藏行为,但配置对象应仅包含数据。
  • 在应用程序启动期间加载配置值,并将这些配置对象注册为容器中的Singleton