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

依赖注入:静态参数与服务注入配置问题

How to Inject MyService with Auto-Resolved Dependencies + Manual Connection String

Hey, I’ve dealt with this exact scenario plenty of times—you want DI to handle the IService1 and IService2 dependencies automatically, but need to pass a specific connectionString from config without messy workarounds. Here are two clean, practical solutions:

Option 1: Use a Factory Delegate in DI Registration

This is the most direct approach. You can leverage the DI container's factory overload to let it resolve your service dependencies, while you manually pass the connection string pulled from configuration.

In your Program.cs (or Startup.cs for older .NET versions):

// Pull the connection string from your config (appsettings.json, environment vars, etc.)
var connectionString = builder.Configuration.GetConnectionString("YourDbConnection");

// Register IMyService with a factory that handles the instance creation
builder.Services.AddScoped<IMyService>(serviceProvider =>
{
    // Let DI resolve the required services for you
    var service1 = serviceProvider.GetRequiredService<IService1>();
    var service2 = serviceProvider.GetRequiredService<IService2>();
    
    // Manually pass the connection string to create your MyService instance
    return new MyService(service1, service2, connectionString);
});

This keeps things simple, no extra classes needed, and exactly matches your requirement: auto-inject the two services, manual connection string.

Option 2: Use the IOptions Pattern (For Cleaner Configuration Management)

If you prefer following .NET's configuration best practices (and want to make future config changes easier), wrap your connection string in a settings class and use IOptions<T>.

  1. First, create a settings class to hold your config values:
public class MyServiceConfig
{
    public string ConnectionString { get; set; } = string.Empty;
}
  1. Add the config to your appsettings.json:
{
  "MyServiceConfig": {
    "ConnectionString": "Server=myServer;Database=myDb;Trusted_Connection=True;"
  }
}
  1. Bind the config and register your service:
// Bind the config section to your MyServiceConfig class
builder.Services.Configure<MyServiceConfig>(builder.Configuration.GetSection("MyServiceConfig"));

// Register IMyService using the factory pattern (no changes to MyService needed)
builder.Services.AddScoped<IMyService>(sp =>
{
    var service1 = sp.GetRequiredService<IService1>();
    var service2 = sp.GetRequiredService<IService2>();
    var config = sp.GetRequiredService<IOptions<MyServiceConfig>>().Value;
    
    return new MyService(service1, service2, config.ConnectionString);
});

If you’re open to modifying MyService’s constructor, you can simplify even further by injecting IOptions<MyServiceConfig> directly:

public class MyService : IMyService 
{ 
    public MyService(IService1 service1, IService2 service2, IOptions<MyServiceConfig> config)
    { 
        string connectionString = config.Value.ConnectionString;
        // Use the connection string here
    } 
}

Then registration becomes as simple as:

builder.Services.Configure<MyServiceConfig>(builder.Configuration.GetSection("MyServiceConfig"));
builder.Services.AddScoped<IMyService, MyService>();

Why Not Just Register a String Directly?

You might have tried registering string with DI, but this is risky—since string is a generic type, the container won’t know which string to resolve if you have multiple registered. The above methods avoid that ambiguity entirely.


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:05:13