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

如何用Simple Injector注入特定IConnector实现并实现条件注册

Hey there! Let's walk through how to set up this conditional dependency injection properly, step by step. I'll focus on Microsoft.Extensions.DependencyInjection first (since it's the default for most .NET projects), and also touch on Autofac in case you're using that.

Conditional DI Setup for Your Worker & Connector Scenario

First, Let's Confirm the Class Structure

Just to align on what we're working with, here's the core type setup based on your description:

// Your base interfaces and implementations
public interface IConnector { }
public class SomeConnector : IConnector
{
    // Depends on its own exclusive context
    public SomeConnector(IConnectorContext context)
    {
        // Initialize using context properties like Types/DataTimeoutSeconds
    }
}

public interface IConnectorContext { }
public class SomeConnectorContext : IConnectorContext
{
    public string Types { get; set; }
    public int DataTimeoutSeconds { get; set; }
}

// Worker classes with specific dependencies
public class Worker1
{
    // Needs two distinct IConnector instances (each with their own context)
    public Worker1(IConnector connector1, IConnector connector2) { }
}

public class Worker2
{
    // Needs one IConnector with its specific context
    public Worker2(IConnector connector) { }
}

Step 1: Implement Conditional Registration Logic

The key here is branching based on your workerType config value. We'll use a switch statement to keep things clean, and leverage named services when we need multiple instances of the same interface (like two IConnectors for Worker1).

For Microsoft.Extensions.DependencyInjection:

var services = new ServiceCollection();
var workerType = Properties.Settings.Default.WorkerType;

switch (workerType)
{
    case "worker1":
        // Register first Connector + its exclusive context
        services.AddSingleton<IConnectorContext>(_ => new SomeConnectorContext
        {
            Types = "Connector1Type", // Adjust these values to your needs
            DataTimeoutSeconds = 30
        });
        services.AddSingleton<IConnector>(sp => 
            new SomeConnector(sp.GetRequiredService<IConnectorContext>()));

        // Register second Connector + its separate context (use a named service to avoid conflict)
        services.AddSingleton<IConnectorContext>("Worker1Connector2Context", _ => new SomeConnectorContext
        {
            Types = "Connector2Type",
            DataTimeoutSeconds = 60
        });
        services.AddSingleton<IConnector>("Worker1Connector2", sp => 
            new SomeConnector(sp.GetRequiredService<IConnectorContext>("Worker1Connector2Context")));

        // Register Worker1, explicitly injecting both named Connectors
        services.AddSingleton<Worker1>(sp => new Worker1(
            sp.GetRequiredService<IConnector>(), // Uses the first (unnamed) Connector
            sp.GetRequiredService<IConnector>("Worker1Connector2")
        ));
        break;

    case "worker2":
        // Register Worker2's single Connector + context
        services.AddSingleton<IConnectorContext>(_ => new SomeConnectorContext
        {
            Types = "Worker2ConnectorType",
            DataTimeoutSeconds = 45
        });
        services.AddSingleton<IConnector, SomeConnector>();
        services.AddSingleton<Worker2>();
        break;

    default:
        throw new InvalidOperationException($"Unsupported worker type: {workerType}");
}

If You're Using Autofac:

If your project uses Autofac instead, the logic is similar—just with Autofac's registration syntax:

var builder = new ContainerBuilder();
var workerType = Properties.Settings.Default.WorkerType;

switch (workerType)
{
    case "worker1":
        // First Connector + context
        builder.Register(_ => new SomeConnectorContext 
        { 
            Types = "Connector1Type", 
            DataTimeoutSeconds = 30 
        }).As<IConnectorContext>().SingleInstance();
        builder.RegisterType<SomeConnector>()
               .Named<IConnector>("Worker1Connector1")
               .SingleInstance();

        // Second Connector + its unique context (named to avoid overlap)
        builder.Register(_ => new SomeConnectorContext 
        { 
            Types = "Connector2Type", 
            DataTimeoutSeconds = 60 
        }).Named<IConnectorContext>("Worker1Connector2Context").SingleInstance();
        builder.Register(ctx => new SomeConnector(
            ctx.ResolveNamed<IConnectorContext>("Worker1Connector2Context")))
               .Named<IConnector>("Worker1Connector2")
               .SingleInstance();

        // Register Worker1 with both named Connectors
        builder.Register(ctx => new Worker1(
            ctx.ResolveNamed<IConnector>("Worker1Connector1"),
            ctx.ResolveNamed<IConnector>("Worker1Connector2")))
               .AsSelf().SingleInstance();
        break;

    case "worker2":
        builder.Register(_ => new SomeConnectorContext 
        { 
            Types = "Worker2ConnectorType", 
            DataTimeoutSeconds = 45 
        }).As<IConnectorContext>().SingleInstance();
        builder.RegisterType<SomeConnector>().As<IConnector>().SingleInstance();
        builder.RegisterType<Worker2>().AsSelf().SingleInstance();
        break;

    default:
        throw new InvalidOperationException($"Unsupported worker type: {workerType}");
}

var container = builder.Build();

Key Things to Note

  • Named Services: When you need multiple instances of the same interface (like two IConnectors for Worker1), named services let you distinguish between them so the DI container knows which one to inject where.
  • Exclusive Contexts: Each SomeConnector gets its own unique SomeConnectorContext instance—we never reuse a context between connectors unless you specifically want that (which you said you don't!).
  • Clean Conditional Logic: Using a switch statement makes it easy to add new worker types later without cluttering up your registration code.

That's it! This setup will handle your conditional registration needs perfectly, ensuring each Worker gets exactly the Connectors and contexts it requires based on your workerType config.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:40:52