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

向类注入工厂以动态创建资源是否为依赖注入最佳实践?

问题解答

1. 注入工厂是否为合理的最佳实践?

你的这种注入工厂接口的做法完全合理,甚至在需要动态创建数量不确定的对象(比如你这里通过XML配置的N个Requester)的场景下,是非常推荐的实践。

核心原因:

  • 遵循控制反转(IoC)原则:Application没有直接创建Requester,而是通过注入的工厂接口获取实例,把对象创建的控制权交给外部。
  • 符合依赖倒置原则:只要给RequesterFactory定义对应的IRequesterFactory接口,Application依赖的就是抽象而非具体实现,你可以轻松替换工厂——比如测试时用返回模拟Requester的工厂,不用依赖真实XML配置,大幅降低测试成本。
  • 完美适配动态场景:DI容器启动时没法预先注册所有Requester(数量由运行时配置决定),通过工厂延迟创建实例,刚好解决了这个核心问题。

唯一要补的细节:给RequesterFactory定义IRequesterFactory接口,确保依赖抽象而非具体类。

2. 如何通过依赖注入创建XML配置的N个对象?

结合你的场景,具体步骤如下:

第一步:完善接口定义

先给工厂定义抽象接口,保证依赖倒置:

public interface IRequesterFactory
{
    List<Requester> CreateRequesters();
}

// 让具体工厂实现接口
public class RequesterFactory : IRequesterFactory
{
    // 你的现有代码...
}

第二步:在工厂中解析配置并创建实例

在CreateRequesters方法里,通过注入的IConfigurationManager读取XML配置,解析每个服务器的信息(地址、请求文件列表等),再逐个创建Requester实例。

如果Requester本身有依赖(比如ILogger、HttpClient),不要直接new,可以通过DI容器的服务提供者来创建带依赖的实例,工厂里使用服务定位器是可接受的场景:

public class RequesterFactory : IRequesterFactory
{
    private readonly IConfigurationManager _configurationManager;
    private readonly IServiceProvider _serviceProvider;

    // 注入服务提供者,用来创建带依赖的Requester
    public RequesterFactory(IConfigurationManager configurationManager, IServiceProvider serviceProvider)
    {
        _configurationManager = configurationManager;
        _serviceProvider = serviceProvider;
    }

    public List<Requester> CreateRequesters()
    {
        var requesters = new List<Requester>();
        // 从XML读取所有服务器配置
        var serverConfigs = _configurationManager.GetServerConfigurations();
        
        foreach (var config in serverConfigs)
        {
            // 用ActivatorUtilities创建带依赖+配置参数的Requester实例
            var requester = ActivatorUtilities.CreateInstance<Requester>(
                _serviceProvider, 
                config.ServerUrl, 
                config.RequestFiles
            );
            
            requesters.Add(requester);
        }

        return requesters;
    }
}

第三步:注册DI服务

把相关服务注册到DI容器(以ASP.NET Core为例):

services.AddSingleton<IConfigurationManager, XmlConfigurationManager>();
services.AddSingleton<IRequesterFactory, RequesterFactory>();
services.AddTransient<Requester>(); // 每个Requester对应不同配置,用Transient生命周期

第四步:修正Application代码错误

你的代码里有两处小问题,修正后:

public class Application : IApplication
{
    private readonly List<Requester> _requesters = [];

    public Application(IRequesterFactory requesterFactory)
    {
        _requesters.AddRange(requesterFactory.CreateRequesters());
    }

    public void RequestFiles()
    {
        foreach(Requester requester in _requesters)
        {
            requester.RequestFiles();
        }
    }
}

这样整个流程就完整了:DI容器注入工厂,工厂根据XML配置动态创建Requester实例,Application只负责调用实例方法,完全符合DI和IoC的设计原则。


内容的提问来源于stack exchange,提问作者Álvaro García

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 05:00:57