如何在静态类中初始化Repository并实现依赖注入?
静态类注入依赖的解决方案
静态类的核心限制是静态构造函数不能接收参数,且无法通过常规构造注入方式获取依赖。针对你的需求,这里提供几种可行的实现方案:
方案1:添加静态初始化方法(保留静态类)
给静态类添加公开的初始化方法,让DI容器在应用启动时主动注入所需依赖:
public static class Utility { private static IBrandRepository _brandRepository; private static IModelRepository _modelRepository; // 供DI容器调用的初始化入口 public static void Initialize(IBrandRepository brandRepo, IModelRepository modelRepo) { _brandRepository = brandRepo ?? throw new ArgumentNullException(nameof(brandRepo)); _modelRepository = modelRepo ?? throw new ArgumentNullException(nameof(modelRepo)); } public static IEnumerable<T_IFS_BrandDTO> GetBrands(int categoryID) { EnsureDependenciesReady(); return _brandRepository.GetAllByCategory(categoryID); } public static IEnumerable<T_IFS_ModelDTO> GetModels(int brandID, int categoryID) { EnsureDependenciesReady(); return _modelRepository.GetAllByBrand(brandID, categoryID); } // 校验依赖是否已初始化 private static void EnsureDependenciesReady() { if (_brandRepository == null || _modelRepository == null) { throw new InvalidOperationException("Utility类未完成初始化,请先调用Initialize方法注入依赖"); } } }
初始化方式(以ASP.NET Core为例)
在应用启动时(比如Program.cs),从DI容器中获取依赖并调用初始化:
var builder = WebApplication.CreateBuilder(args); // 先注册你的仓库服务 builder.Services.AddScoped<IBrandRepository, BrandRepository>(); builder.Services.AddScoped<IModelRepository, ModelRepository>(); var app = builder.Build(); // 初始化静态类 var brandRepo = app.Services.GetRequiredService<IBrandRepository>(); var modelRepo = app.Services.GetRequiredService<IModelRepository>(); Utility.Initialize(brandRepo, modelRepo); // 后续启动逻辑 app.Run();
如果想更优雅地初始化,可以用IHostedService:
public class UtilityInitializer : IHostedService { private readonly IBrandRepository _brandRepo; private readonly IModelRepository _modelRepo; public UtilityInitializer(IBrandRepository brandRepo, IModelRepository modelRepo) { _brandRepo = brandRepo; _modelRepo = modelRepo; } public Task StartAsync(CancellationToken cancellationToken) { Utility.Initialize(_brandRepo, _modelRepo); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; } // 注册到DI builder.Services.AddHostedService<UtilityInitializer>();
方案2:改用单例服务(推荐,符合DI设计原则)
如果不是必须使用静态类,推荐将Utility改为单例服务,通过构造注入获取依赖,这是最符合依赖倒置原则的实现方式:
// 定义接口 public interface IUtilityService { IEnumerable<T_IFS_BrandDTO> GetBrands(int categoryID); IEnumerable<T_IFS_ModelDTO> GetModels(int brandID, int categoryID); } // 实现类 public class UtilityService : IUtilityService { private readonly IBrandRepository _brandRepository; private readonly IModelRepository _modelRepository; // 构造注入依赖 public UtilityService(IBrandRepository brandRepository, IModelRepository modelRepository) { _brandRepository = brandRepository ?? throw new ArgumentNullException(nameof(brandRepository)); _modelRepository = modelRepository ?? throw new ArgumentNullException(nameof(modelRepository)); } public IEnumerable<T_IFS_BrandDTO> GetBrands(int categoryID) { return _brandRepository.GetAllByCategory(categoryID); } public IEnumerable<T_IFS_ModelDTO> GetModels(int brandID, int categoryID) { return _modelRepository.GetAllByBrand(brandID, categoryID); } }
注册与使用
在DI容器中注册为单例:
builder.Services.AddSingleton<IUtilityService, UtilityService>();
在需要使用的类中,通过构造注入IUtilityService即可:
public class SomeService { private readonly IUtilityService _utilityService; public SomeService(IUtilityService utilityService) { _utilityService = utilityService; } public void DoSomething() { var brands = _utilityService.GetBrands(1); // ... } }
这种方式的优势是依赖关系清晰,易于单元测试,也符合.NET生态的DI规范。
方案3:服务定位器模式(不推荐)
如果必须保留静态类且无法提前初始化,可以通过服务定位器从DI容器中直接获取依赖,但这种方式会隐藏依赖关系,降低代码可维护性和可测试性:
public static class Utility { private static IServiceProvider _serviceProvider; // 设置DI容器的服务提供者 public static void SetServiceProvider(IServiceProvider provider) { _serviceProvider = provider ?? throw new ArgumentNullException(nameof(provider)); } public static IEnumerable<T_IFS_BrandDTO> GetBrands(int categoryID) { var repo = _serviceProvider.GetRequiredService<IBrandRepository>(); return repo.GetAllByCategory(categoryID); } public static IEnumerable<T_IFS_ModelDTO> GetModels(int brandID, int categoryID) { var repo = _serviceProvider.GetRequiredService<IModelRepository>(); return repo.GetAllByBrand(brandID, categoryID); } }
初始化方式
在应用启动时设置服务提供者:
var app = builder.Build(); Utility.SetServiceProvider(app.Services);
内容的提问来源于stack exchange,提问作者Steve Cross
相关产品推荐
相关产品推荐

