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
相关产品推荐
相关产品推荐

