You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET应用配置对象注入:SimpleInjector获取IConfiguration最佳方案

Great question! Ditching that static container wrapper is absolutely the right call—static service locators are an anti-pattern that hides dependencies, hurts testability, and makes your code harder to maintain. Let’s walk through the cleanest, most maintainable solution to refactor your Linq2Db settings class with proper dependency injection using SimpleInjector and IConfiguration.

Step 1: Refactor Linq2DbSettings to use constructor injection

Instead of reaching for a static container, we’ll explicitly inject IConfiguration into your settings class via its constructor. This makes the class’s dependencies clear, and lets SimpleInjector handle resolving them automatically.

Here’s the updated code:

using Microsoft.Extensions.Configuration;
using LinqToDB.Configuration;

public class Linq2DbSettings : ILinqToDBSettings
{
    private readonly IConfiguration _configuration;

    // Inject IConfiguration directly via constructor—no static containers needed!
    public Linq2DbSettings(IConfiguration configuration)
    {
        _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
    }

    public IEnumerable<IDataProviderSettings> DataProviders 
    { 
        get { yield break; } 
    }

    public string DefaultConfiguration => "SqlServer";
    public string DefaultDataProvider => ProviderName.SqlServer;

    public IEnumerable<IConnectionStringSettings> ConnectionStrings
    {
        get
        {
            yield return new ConnectionStringSettings
            {
                Name = "SqlServer",
                ProviderName = "SqlServer",
                // Pull the connection string from IConfiguration (works with appsettings.json, environment vars, etc.)
                ConnectionString = _configuration.GetConnectionString("Default")
            };
        }
    }
}

// Your existing ConnectionStringSettings class stays the same
public class ConnectionStringSettings : IConnectionStringSettings
{
    public string ConnectionString { get; set; }
    public string Name { get; set; }
    public string ProviderName { get; set; }
    public bool IsGlobal => false;
}

Step 2: Register your settings with SimpleInjector

Since you already have IConfiguration registered in your SimpleInjector container, all you need to do is register ILinqToDBSettings to resolve to your Linq2DbSettings class. Add this to your container configuration code:

// Register as a singleton since settings don't change at runtime
container.Register<ILinqToDBSettings, Linq2DbSettings>(Lifestyle.Singleton);

For even better maintainability, you can bind your Linq2Db settings to a strongly-typed class instead of accessing IConfiguration directly. This makes your configuration easier to validate and refactor.

  1. First, add a config section to your appsettings.json (or config source):
{
  "Linq2Db": {
    "DefaultConfiguration": "SqlServer",
    "DefaultDataProvider": "SqlServer",
    "ConnectionStrings": [
      {
        "Name": "SqlServer",
        "ProviderName": "SqlServer",
        "ConnectionString": "Your_Connection_String_Here"
      }
    ]
  }
}
  1. Create a strongly-typed config class:
public class Linq2DbConfig
{
    public string DefaultConfiguration { get; set; }
    public string DefaultDataProvider { get; set; }
    public List<ConnectionStringSettings> ConnectionStrings { get; set; }
}
  1. Update Linq2DbSettings to use this class:
public class Linq2DbSettings : ILinqToDBSettings
{
    private readonly Linq2DbConfig _config;

    public Linq2DbSettings(Linq2DbConfig config)
    {
        _config = config ?? throw new ArgumentNullException(nameof(config));
    }

    public IEnumerable<IDataProviderSettings> DataProviders 
    { 
        get { yield break; } 
    }

    public string DefaultConfiguration => _config.DefaultConfiguration;
    public string DefaultDataProvider => _config.DefaultDataProvider;

    public IEnumerable<IConnectionStringSettings> ConnectionStrings => _config.ConnectionStrings;
}
  1. Bind the config section and register it in SimpleInjector:
// Bind the config section to our strongly-typed class
var linq2DbConfig = configuration.GetSection("Linq2Db").Get<Linq2DbConfig>();
container.RegisterInstance(linq2DbConfig);

// Register the settings class as before
container.Register<ILinqToDBSettings, Linq2DbSettings>(Lifestyle.Singleton);

Why this works (and why it’s better than static containers)

  • Clear dependencies: Your Linq2DbSettings class explicitly declares what it needs to work, making your code easier to read and debug.
  • Testability: You can easily mock IConfiguration or your strongly-typed Linq2DbConfig for unit tests, without needing to spin up a full container.
  • Follows SOLID principles: This adheres to the Dependency Inversion Principle, keeping your settings class decoupled from configuration implementation details.
  • No hidden dependencies: Static containers hide where dependencies come from—constructor injection makes everything transparent.

内容的提问来源于stack exchange,提问作者advapi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:53:00