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

Autofac中工厂(Func<>)的动态实例化方案咨询

用Autofac的Func<>委托实现解耦的工厂模式

你说得太对了——直接在工厂类里硬编码调用容器的Resolve<T>()确实会把你的业务代码和Autofac容器强绑定,完全违背了依赖注入的解耦初衷。用Func<>委托来实现动态实例化是更优雅的做法,而且Autofac本身就对Func<>有原生支持,不用自己写复杂的工厂实现。

下面一步步帮你完成这个实现:

1. 完善SomethingManager的依赖注入

首先把你的SomethingManager补全,确保它依赖的是Func<>委托而不是直接依赖容器。这里提供两种方案,推荐用类型更安全的泛型版本:

选项A:泛型版本(更类型安全)

public interface IRepository<T> { }
public class UserRepository : IRepository<User> { }
public class OrderRepository : IRepository<Order> { }

public class SomethingManager
{
    // 注入泛型Func,用于创建指定类型的IRepository<T>
    private readonly Func<IRepository<User>> _userRepositoryFactory;
    private readonly Func<IRepository<Order>> _orderRepositoryFactory;

    // 构造注入
    public SomethingManager(Func<IRepository<User>> userRepositoryFactory, 
                           Func<IRepository<Order>> orderRepositoryFactory)
    {
        _userRepositoryFactory = userRepositoryFactory;
        _orderRepositoryFactory = orderRepositoryFactory;
    }

    public void DoBusinessLogic()
    {
        // 动态创建仓库实例,完全不依赖容器
        var userRepo = _userRepositoryFactory();
        var orderRepo = _orderRepositoryFactory();
        
        // 执行业务逻辑...
    }
}

选项B:基于Type参数的版本(兼容你的初始代码)

如果你需要通过Type参数动态创建任意IRepository实现,可以用这个版本:

public interface IRepository { }
public class UserRepository : IRepository { }
public class OrderRepository : IRepository { }

public class SomethingManager
{
    private readonly Func<Type, IRepository> _repositoryFactory;

    public SomethingManager(Func<Type, IRepository> repositoryFactory)
    {
        _repositoryFactory = repositoryFactory;
    }

    public void DoBusinessLogic()
    {
        // 通过Type参数创建指定仓库
        var userRepo = _repositoryFactory(typeof(UserRepository));
        var orderRepo = _repositoryFactory(typeof(OrderRepository));
        
        // 执行业务逻辑...
    }
}

2. 配置Autofac容器注册

关键来了:Autofac会自动为你生成Func<>委托的实现,你只需要正常注册你的IRepository及其实现类即可,不需要额外注册Func<>!

var builder = new ContainerBuilder();

// 对应选项A的泛型注册
builder.RegisterType<UserRepository>().As<IRepository<User>>();
builder.RegisterType<OrderRepository>().As<IRepository<Order>>();

// 对应选项B的非泛型注册(如果用选项B就打开这段)
// builder.RegisterType<UserRepository>().As<IRepository>();
// builder.RegisterType<OrderRepository>().As<IRepository>();

// 注册你的业务类SomethingManager
builder.RegisterType<SomethingManager>();

var container = builder.Build();

3. 使用方式

现在你只需要从容器中解析SomethingManager,剩下的实例化逻辑都由Autofac的Func<>委托自动处理:

var manager = container.Resolve<SomethingManager>();
manager.DoBusinessLogic();

为什么这种方式更好?

  • 完全解耦:SomethingManager不再依赖Autofac容器,只依赖Func<>这个通用委托,符合依赖倒置原则。
  • 易于测试:单元测试时,你可以轻松传入一个自定义的Func<>委托,模拟仓库实例,不需要启动整个DI容器。
  • Autofac原生支持:不需要自己编写工厂类,减少冗余代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:46:21