.NET Core中如何传递带参数构造函数的泛型类型?
解决泛型类型中使用带参数构造函数的问题
错误原因
当前基控制器的UpdateTheStatus方法对TService添加了new()约束,要求类型必须拥有公开无参构造函数,但UserService仅提供了带MyContext参数的构造函数,不符合约束要求,因此触发报错。
解决方案
以下提供几种可行的修复方式,优先推荐契合ASP.NET Core设计理念的依赖注入方案:
方案1:通过依赖注入注入服务(推荐)
修改基控制器逻辑,让服务实例由依赖注入容器管理,而非手动创建:
- 调整基控制器的泛型方法,接收已实例化的服务对象:
public abstract class AdminController : ControllerBase { public async Task UpdateTheStatus<TService, T>(TService service, int id, int status) where TService : StatusService<T> { await service.UpdateStatus(id, status); } }
- 在
UserController中注入UserService并调用方法:
public class UserController : AdminController { private readonly UserService _userService; // 构造函数注入UserService public UserController(UserService userService) { _userService = userService; } public async Task UpdateUserStatus(int id, int status) { await UpdateTheStatus<UserService, User>(_userService, id, status); } }
- 在项目配置文件(如
Program.cs)中注册服务与上下文:
builder.Services.AddScoped<UserService>(); builder.Services.AddDbContext<MyContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
这种方式利用依赖注入容器管理服务生命周期,避免手动实例化带来的耦合问题,符合ASP.NET Core最佳实践。
方案2:移除new()约束,通过反射传递构造参数
若无法使用依赖注入,可通过反射创建服务实例并传入构造参数:
修改基控制器的UpdateTheStatus方法:
public abstract class AdminController : ControllerBase { private readonly MyContext _context; // 注入MyContext用于传递给服务构造函数 public AdminController(MyContext context) { _context = context; } public async Task UpdateTheStatus<TService, T>(int id, int status) where TService : StatusService<T> { // 反射创建TService实例,传入MyContext参数 var service = (TService)Activator.CreateInstance(typeof(TService), _context); await service.UpdateStatus(id, status); } }
此方式无需new()约束,但反射存在一定性能开销,仅适合简单场景。
方案3:添加无参构造函数(不推荐)
给UserService添加无参构造函数,手动实例化MyContext,但会导致代码耦合度升高,不利于维护和测试:
public class UserService : StatusService<User> { // 硬编码实例化MyContext,不推荐 public UserService() : base(new MyContext()) { } public UserService(MyContext context) : base(context) { } }
内容的提问来源于stack exchange,提问作者Howard Hee
相关产品推荐
相关产品推荐

