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

如何在控制台应用中通过Pure DI实现控制反转(不使用IoC容器)

完全可以通过Pure DI的方式实现解耦,无需引入任何第三方IoC容器。核心思路是将「实例创建的能力」作为依赖注入到工厂中,而非让工厂直接依赖具体实现,所有实现的绑定逻辑统一上移到程序的组合根(也就是入口Main方法所在的最高层级)。

改造步骤

1. 重构GummyFactory

将创建IGummyPackage、IGummyBag、IGummyBear实例的逻辑通过构造函数委托的形式注入,让工厂只依赖接口,完全和具体实现解耦:

public class GummyFactory : Factory<IGummyPackage>
{
    private readonly Func<IGummyPackage> _packageFactory;
    private readonly Func<IGummyBag> _bagFactory;
    private readonly Func<IGummyBear> _bearFactory;

    // 构造函数注入三个创建实例的工厂委托
    public GummyFactory(Func<IGummyPackage> packageFactory, 
                        Func<IGummyBag> bagFactory, 
                        Func<IGummyBear> bearFactory)
    {
        _packageFactory = packageFactory;
        _bagFactory = bagFactory;
        _bearFactory = bearFactory;
    }

    public override IGummyPackage AssembleProducts()
    {
        IGummyPackage gummyPackage = _packageFactory();
        Random rnd = new Random();
        
        for (int i=1;i<=GummyBearPackageConfiguration.NumberOfGummieBagsPerPackage;i++)
        {
            IGummyBag gummyBag = _bagFactory();
            gummyBag.BagNumber = i;

            for (int b =1; b <= GummyBearPackageConfiguration.NumberOfGummiesPerBags;b++)
            {
                IGummyBear gummyBear = _bearFactory();
                gummyBear.GummyID = b;

                int flvr = rnd.Next(0, 5);
                gummyBear.flavor = (GummyFlavor)flvr;

                gummyBag.GummyBears.Add(gummyBear);
            }

            gummyPackage.GummyBags.Add(gummyBag);
        }

        return gummyPackage;
    }
}

2. 在组合根绑定实现

所有具体实现的绑定逻辑都放在入口Main方法中,后续替换实现只需要修改这一处即可,无需调整工厂内部逻辑:

class Program
{
    static void Main(string[] args)
    {
        // 加载配置
        GummyBearPackageConfiguration.NumberOfGummieBagsPerPackage = 24;
        GummyBearPackageConfiguration.NumberOfGummiesPerBags = 7;

        // 这里统一绑定具体实现,后续换环保纸盒仅需修改bagFactory对应的逻辑
        var gummyFactory = new GummyFactory(
            packageFactory: () => new GummyPackage(),
            bagFactory: () => new GummyBag(),
            bearFactory: () => new GummyBear()
        );
        
        IGummyPackage gummyPackage = gummyFactory.AssembleProducts();

        OpenPackage(gummyPackage);
        Console.ReadLine();
    }

    // 注意这里要把遍历的类型改为接口,避免和具体实现耦合
    public static void OpenPackage(IGummyPackage package)
    {
        Console.WriteLine($"Opening Gummy Package: \n");
        foreach (IGummyBag bag in package.GummyBags)
        {
            Console.WriteLine($"Opening Gummy Bag #{bag.BagNumber}");

            foreach (IGummyBear bear in bag.GummyBears)
            {
                Console.WriteLine(
                    $"Gummy Number {bear.GummyID} is {bear.flavor.ToString()} flavor");
            }
        }
    }
}

改造收益

  • 完全基于原生C#语法实现,无任何第三方依赖,符合你的项目限制
  • 动态创建实例的需求完美适配:注入的是创建实例的委托,运行时需要多少个实例就调用多少次委托,不受构造注入只能注入固定实例的限制
  • 符合开闭原则:后续更换任意组件实现(比如把GummyBag换成环保硬纸盒),仅需修改组合根的绑定逻辑,无需调整工厂核心的装配代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 07:36:03