.Net Core DI如何实现类似Ninject的ToFactory功能集中管理服务接口
.NET Core 官方依赖注入实现类似 Ninject
.ToFactory() 功能方案 实现思路
.NET Core 官方依赖注入框架没有内置 ToFactory() 这类自动生成工厂实现的API,我们可以通过手动实现服务工厂类+IServiceProvider动态解析的方式达到完全相同的效果,不需要修改原有控制器的调用逻辑。
具体实现步骤
步骤1:沿用原有工厂接口定义
和你之前在Ninject中使用的接口完全一致:
public interface IAppServiceFactory { IAccessAgreementAppService AccessAgreement { get; } IAccessAgreementUserAppService AccessAgreementUser { get; } // 后续新增服务只需要在此处添加对应属性即可 }
步骤2:实现工厂类
工厂类构造函数注入IServiceProvider,每个属性从容器中动态解析对应服务:
public class AppServiceFactory : IAppServiceFactory { private readonly IServiceProvider _serviceProvider; public AppServiceFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } public IAccessAgreementAppService AccessAgreement => _serviceProvider.GetRequiredService<IAccessAgreementAppService>(); public IAccessAgreementUserAppService AccessAgreementUser => _serviceProvider.GetRequiredService<IAccessAgreementUserAppService>(); // 对应接口新增的属性,在此处添加解析逻辑即可 }
步骤3:注册服务与工厂
在Program.cs(.NET 6+)或Startup.cs的服务注册区域,先注册所有业务服务,再注册工厂:
// 注册你的业务服务 builder.Services.AddScoped<IAccessAgreementAppService, AccessAgreementAppService>(); builder.Services.AddScoped<IAccessAgreementUserAppService, AccessAgreementUserAppService>(); // 其他服务注册... // 注册服务工厂,生命周期和业务服务保持一致即可,通常业务服务为Scoped,工厂也注册为Scoped builder.Services.AddScoped<IAppServiceFactory, AppServiceFactory>();
步骤4:控制器调用
和你之前Ninject栈的调用逻辑完全一致,不需要修改原有代码:
private readonly IMapper _mapper; private readonly IAppServiceFactory _appServiceFactory; public MyController(IMapper mapper, IAppServiceFactory appServiceFactory) { _mapper = mapper; _appServiceFactory = appServiceFactory; } public ActionResult Index() { var all = _appServiceFactory.AccessAgreementUser.GetAll(); // 其他业务逻辑 }
注意事项
- 工厂的生命周期需要和内部解析的服务生命周期匹配:如果你的业务服务都是Scoped(默认常用的请求级生命周期),工厂就注册为Scoped;如果业务服务是Singleton,工厂可注册为Singleton,注意不要在Singleton的工厂中解析Scoped服务,会导致服务生命周期异常。
- 新增业务服务时,只需要在IAppServiceFactory中加属性,同时在AppServiceFactory中加对应的解析逻辑即可,维护成本很低。
- 如果项目服务数量极多,不想手动写属性解析逻辑,可以自己写源生成器自动生成AppServiceFactory的实现代码,进一步减少重复工作。
内容的提问来源于stack exchange,提问作者Antonio Luiz Pires Filho
相关产品推荐
相关产品推荐

