使用Autofac聚合服务解决ASP.NET Web API 2共享依赖注入问题
使用Autofac聚合服务优化ASP.NET Web API 2的重复依赖注入
嘿,我完全懂这种重复注入的痛苦——10个控制器每个都要写那四个服务的构造函数参数,不仅繁琐还容易出错。Autofac的聚合服务(Aggregate Services)就是专门解决这种场景的,下面给你一步步拆解实现方法:
1. 定义聚合服务接口与实现类
首先,我们把所有控制器共享的4个服务打包成一个聚合服务。先创建一个接口,包含所有共享服务的只读属性,再写对应的实现类,通过构造函数注入这些服务并赋值:
// 聚合服务接口,定义所有共享服务的访问入口 public interface ICommonServices { IService1 FirstService { get; } IService2 SecondService { get; } IService3 ThirdService { get; } IService4 FourthService { get; } } // 聚合服务实现类,负责注入并持有所有共享服务 public class CommonServices : ICommonServices { // 用只读属性确保依赖不会被意外修改 public IService1 FirstService { get; } public IService2 SecondService { get; } public IService3 ThirdService { get; } public IService4 FourthService { get; } // 构造函数注入所有需要的共享服务 public CommonServices( IService1 firstService, IService2 secondService, IService3 thirdService, IService4 fourthService) { FirstService = firstService; SecondService = secondService; ThirdService = thirdService; FourthService = fourthService; } }
2. 配置Autofac容器注册
接下来在Autofac的容器配置中,除了注册原来的4个服务,还要注册我们的聚合服务:
var builder = new ContainerBuilder(); // 注册原始的各个服务(这一步你应该已经在做了,这里只是确认) builder.RegisterType<Service1>().As<IService1>(); builder.RegisterType<Service2>().As<IService2>(); builder.RegisterType<Service3>().As<IService3>(); builder.RegisterType<Service4>().As<IService4>(); // 注册聚合服务 builder.RegisterType<CommonServices>().As<ICommonServices>(); // 注册所有Web API控制器 builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); // 替换Web API的依赖解析器 var container = builder.Build(); GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
3. 修改控制器的构造函数注入
现在所有控制器只需要注入这个聚合服务即可,不用再一个个写那4个服务的参数了:
public class Controller1 : ApiController { private readonly ICommonServices _commonServices; // 构造函数只需要注入聚合服务 public Controller1(ICommonServices commonServices) { _commonServices = commonServices; } public IHttpActionResult Get() { // 使用时通过聚合服务访问各个子服务 var result = _commonServices.FirstService.ProcessData(); return Ok(result); } }
额外的好处
- 维护性提升:以后如果需要新增或修改共享服务,只需要修改聚合服务的接口和实现,所有控制器的构造函数都不用动。
- 代码简洁性:控制器的构造函数变得清爽,减少了重复代码,也降低了构造函数参数过多的“参数膨胀”问题。
- 依赖清晰:聚合服务明确了哪些是控制器的公共依赖,让代码结构更直观。
内容的提问来源于stack exchange,提问作者Sibtain Norain
相关产品推荐
相关产品推荐

