Autofac依赖注入问题:工厂类中如何注入依赖接口实例
解决Autofac中工厂类依赖注入的问题
刚上手Autofac遇到这种场景太正常了,静态工厂确实没法直接拿到容器里的依赖实例,我给你几个实用的解决方案,你可以根据自己的场景选:
方案1:将工厂改为非静态,注入Autofac的组件上下文
把你的静态工厂改成普通类,让Autofac给它注入IComponentContext(或者ILifetimeScope,如果需要管理实例生命周期的话),这样就能从容器里直接解析需要的EmployerMetaDataSaver,Autofac会自动帮你注入它的IEmployerFunctions依赖:
public class MetaDataSaverFactory { private readonly IComponentContext _componentContext; // 让Autofac自动注入组件上下文 public MetaDataSaverFactory(IComponentContext componentContext) { _componentContext = componentContext; } public IMetaDataSaver GetMetaDataSaver(HttpRequestMessage request) { if (request.IsReciprocal()) { // 如果ReciprocalMetaDataSaver有依赖,同样用Resolve获取 return _componentContext.Resolve<ReciprocalMetaDataSaver>(); } else { // Autofac会自动注入IEmployerFunctions到EmployerMetaDataSaver return _componentContext.Resolve<EmployerMetaDataSaver>(); } } }
然后别忘了在Autofac注册这个工厂:
builder.RegisterType<MetaDataSaverFactory>();
之后在需要使用工厂的地方,注入这个MetaDataSaverFactory实例,而不是调用静态方法,比如:
public class YourService { private readonly MetaDataSaverFactory _saverFactory; public YourService(MetaDataSaverFactory saverFactory) { _saverFactory = saverFactory; } public void ProcessRequest(HttpRequestMessage request) { var saver = _saverFactory.GetMetaDataSaver(request); // 处理业务逻辑... } }
方案2:使用Autofac的委托工厂(更简洁)
Autofac支持委托工厂,不需要自己写工厂类,先定义一个委托:
public delegate IMetaDataSaver MetaDataSaverFactory(HttpRequestMessage request);
然后在Autofac的注册代码里,实现这个委托的逻辑:
builder.Register<MetaDataSaverFactory>(context => { var componentContext = context.Resolve<IComponentContext>(); return request => { return request.IsReciprocal() ? componentContext.Resolve<ReciprocalMetaDataSaver>() : componentContext.Resolve<EmployerMetaDataSaver>(); }; });
之后在需要创建IMetaDataSaver的地方,直接注入这个委托,调用它就行:
public class YourService { private readonly MetaDataSaverFactory _saverFactory; public YourService(MetaDataSaverFactory saverFactory) { _saverFactory = saverFactory; } public void ProcessRequest(HttpRequestMessage request) { var saver = _saverFactory(request); // 处理业务逻辑... } }
方案3:直接注入工厂所需的依赖(解耦Autofac)
如果不想让工厂依赖Autofac的内部接口,可以把IEmployerFunctions直接注入工厂,然后手动传给EmployerMetaDataSaver:
public class MetaDataSaverFactory { private readonly IEmployerFunctions _employerFunctions; public MetaDataSaverFactory(IEmployerFunctions employerFunctions) { _employerFunctions = employerFunctions; } public IMetaDataSaver GetMetaDataSaver(HttpRequestMessage request) { if (request.IsReciprocal()) { return new ReciprocalMetaDataSaver(); } else { // 手动传入已注入的依赖 return new EmployerMetaDataSaver(_employerFunctions); } } }
这个方案的好处是工厂完全不依赖Autofac,但如果EmployerMetaDataSaver后续增加更多依赖,工厂的构造函数会越来越臃肿,这时候前两个方案会更省心。
小提醒
尽量避免用静态工厂,静态方法不仅没法利用依赖注入,还会让代码难以测试。优先用委托工厂或者注入组件上下文的方式,让Autofac帮你管理所有依赖的生命周期~
内容的提问来源于stack exchange,提问作者coding4fun
相关产品推荐
相关产品推荐

