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

如何在使用Activator的订单评估器工厂中实现依赖注入?

问题场景

我现在有一个静态的OrderEvaluatorFactory,用来创建各类Order Evaluator。现在新增了一种Order Evaluator,它必须通过依赖注入获取IOrderProcessor(只能通过DI获取)。

当前工厂类通过特性查找要实例化的目标类型,再用System.Activator.CreateInstance()创建实例,代码如下:

public static class OrderEvaluatorFactory
{
    private static Dictionary<Type, Type> orderEvaluatorTypesByOrderTypes = null;
    
    public static IOrderEvaluator CreateFor(OrderType ot)
    {
        if (orderEvaluatorTypesByOrderTypes == null)
        {
            orderEvaluatorTypesByOrderTypes = Utilities.TypeFinder<OrderTypeEvaluatorForAttribute, Type>.GetTypesByAttribute(
                typeof(OrderEvaluatorFactory).Assembly, type => typeof(IOrderEvaluator).IsAssignableFrom(type),
                attribute => attribute.For);
        }

        Type orderEvaluatorType = evaluatorTypesByOrderTypes[ot.GetType()];

        if (evaluatorType == null)
            throw new Exception("No evaluator type found for " + ot.GetType());

        return (IOrderEvaluator)Activator.CreateInstance(evaluatorType);
    }
}

需要依赖注入的评估器代码:

[OrderTypeEvaluatorFor(typeof(SuperFastDeliveryOrder))]
public class SuperFastDeliveryOrderEvaluator : IOrderEvaluator
{
    private readonly IOrderProcessor orderProcessor;
    
    public SuperFastDeliveryOrderEvaluator(IOrderProcessor orderProcessor)
    {
        this.orderProcessor = orderProcessor;
    }

    public bool Eval(Customer cstm)
    {
        // 省略实现...
        return true;
    }
}

这是目前唯一需要IOrderProcessor的评估器,所以我不想给所有其他评估器都传递这个对象(比如作为参数)。

现在遇到的问题:带IOrderProcessor的构造函数无法被Activator.CreateInstance()调用(它只会调用无参构造),而且我不想通过重载给所有对象都传IOrderProcessor。

我知道静态工厂模式和DI不太兼容,但找不到合适的解决方案。我考虑过把工厂改成非静态并加入DI容器,这样就能传入IOrderProcessor,但还是得保留Activator的逻辑。

请问怎么替换Activator,用更适配DI的方式,同时不用硬编码所有已知评估器的实例逻辑?

解决方案

方案1:将工厂改为非静态,注入DI容器并使用容器解析实例

把静态工厂改成实例类,注入DI容器的服务提供器,让容器负责解析评估器的构造函数依赖,替代Activator.CreateInstance。

步骤如下:

  1. 改造工厂类为非静态,注入IServiceProvider:
public class OrderEvaluatorFactory
{
    private readonly IServiceProvider _serviceProvider;
    private Dictionary<Type, Type> _orderEvaluatorTypesByOrderTypes;

    public OrderEvaluatorFactory(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
        InitializeTypeMapping();
    }

    private void InitializeTypeMapping()
    {
        _orderEvaluatorTypesByOrderTypes = Utilities.TypeFinder<OrderTypeEvaluatorForAttribute, Type>.GetTypesByAttribute(
            typeof(OrderEvaluatorFactory).Assembly, 
            type => typeof(IOrderEvaluator).IsAssignableFrom(type),
            attribute => attribute.For);
    }

    public IOrderEvaluator CreateFor(OrderType ot)
    {
        if (!_orderEvaluatorTypesByOrderTypes.TryGetValue(ot.GetType(), out var evaluatorType))
        {
            throw new InvalidOperationException($"No evaluator type found for {ot.GetType()}");
        }

        // 用DI容器解析实例,自动处理构造函数依赖
        return (IOrderEvaluator)_serviceProvider.GetService(evaluatorType);
    }
}
  1. 在DI容器中注册所有IOrderEvaluator实现类及工厂:
// 以Microsoft.Extensions.DependencyInjection为例
services.AddTransient<IOrderProcessor, OrderProcessor>();
services.AddTransient<SuperFastDeliveryOrderEvaluator>();
// 注册其他无依赖的评估器
services.AddTransient<NormalOrderEvaluator>();
// 注册工厂本身
services.AddSingleton<OrderEvaluatorFactory>();
  1. 在需要创建评估器的地方,通过DI注入OrderEvaluatorFactory并调用CreateFor方法即可。

方案2:针对性处理需要DI的评估器,其余保留Activator创建

如果不想全量用容器解析,可以在工厂里判断评估器类型是否需要IOrderProcessor,单独处理:

public class OrderEvaluatorFactory
{
    private readonly IOrderProcessor _orderProcessor;
    private Dictionary<Type, Type> _orderEvaluatorTypesByOrderTypes;

    public OrderEvaluatorFactory(IOrderProcessor orderProcessor)
    {
        _orderProcessor = orderProcessor;
        InitializeTypeMapping();
    }

    private void InitializeTypeMapping()
    {
        _orderEvaluatorTypesByOrderTypes = Utilities.TypeFinder<OrderTypeEvaluatorForAttribute, Type>.GetTypesByAttribute(
            typeof(OrderEvaluatorFactory).Assembly, 
            type => typeof(IOrderEvaluator).IsAssignableFrom(type),
            attribute => attribute.For);
    }

    public IOrderEvaluator CreateFor(OrderType ot)
    {
        if (!_orderEvaluatorTypesByOrderTypes.TryGetValue(ot.GetType(), out var evaluatorType))
        {
            throw new InvalidOperationException($"No evaluator type found for {ot.GetType()}");
        }

        // 判断是否是需要IOrderProcessor的评估器
        if (evaluatorType == typeof(SuperFastDeliveryOrderEvaluator))
        {
            return new SuperFastDeliveryOrderEvaluator(_orderProcessor);
        }
        else
        {
            // 其他无依赖的用Activator创建
            return (IOrderEvaluator)Activator.CreateInstance(evaluatorType);
        }
    }
}

这种方式适合只有极少数评估器需要DI依赖的场景,但后续新增需要DI的评估器时,需手动添加判断逻辑,扩展性不如方案1。

方案3:容器批量注册+工厂解析

如果使用支持批量注册的DI容器(如Autofac),可以批量注册所有带OrderTypeEvaluatorForAttribute的评估器,再通过容器解析实例:

// Autofac注册示例
builder.RegisterAssemblyTypes(typeof(OrderEvaluatorFactory).Assembly)
       .Where(t => t.GetCustomAttribute<OrderTypeEvaluatorForAttribute>() != null)
       .As<IOrderEvaluator>()
       .InstancePerDependency();

builder.RegisterType<OrderEvaluatorFactory>().SingleInstance();

工厂类逻辑可参考方案1,用IServiceProvider或Autofac的IComponentContext解析实例。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 05:45:41