如何在不使用依赖注入的情况下构造IRepository<Games>实例
报错根因
你抛出的IRepository does not contain a definition for GetSingleGame错误,核心原因有两个:
- 调用位置没有可用的
IRepository<Games>类型实例。扩展方法本质是静态类中定义的静态方法,所谓的实例调用语法只是编译器提供的语法糖,必须有对应类型的实例才能用实例.方法()的形式调用,没有实例的情况下编译器找不到绑定目标,就会抛出方法不存在的错误。 - 未引入扩展方法所在静态类的命名空间,哪怕有实例也会报同样的错,这个可以先检查排除。
脱离依赖注入的调用方案
1. 手动构造仓储实例(完全脱离DI容器场景)
接口无法直接实例化,你需要先找到项目中IRepository<T>对应的具体实现类——也就是你原本在DI容器中注册的那个实现类型,手动传入该类型构造函数需要的所有依赖,完成实例化后即可正常调用扩展方法。
举个例子,假设IRepository<T>的实现类是EfCoreRepository<T>,构造依赖为数据库上下文:
// 先初始化仓储的底层依赖,比如传入配置好的连接字符串初始化DbContext var dbContext = new AppDbContext("你的数据库连接字符串"); // 构造IRepository<Games>实例 IRepository<Games> gamesRepo = new EfCoreRepository<Games>(dbContext); // 正常调用扩展方法 var rpgGame = gamesRepo.GetSingleGame(GameType.RPG); // 用完记得释放实现了IDisposable的依赖,比如dbContext dbContext.Dispose();
手动构造的实例生命周期完全由你自己管控,注意及时释放占用资源的对象,避免内存泄漏。
2. 直接以静态方法形式调用
扩展方法本身就是静态方法,如果你手头已经有IRepository<Games>的实例(不管来源是手动构造还是其他渠道),完全可以不用实例调用语法,直接按普通静态方法的规则传参调用,效果和实例写法完全一致:
// 注意前面要写扩展方法所在静态类的类名,记得引入对应命名空间 var rpgGame = RepositoryExtensions.GetSingleGame(gamesRepo, GameType.RPG);
3. 从已有的DI容器中获取实例(半脱离DI场景)
如果你的控制器只是没有通过构造函数注入依赖,但整个应用本身已经启动完成、DI容器已经注册过IRepository<Games>的对应实现,可以直接在控制器中通过请求上下文获取服务实例,不需要手动new:
// 在控制器的Action方法内直接获取请求域的仓储实例 var gamesRepo = HttpContext.RequestServices.GetRequiredService<IRepository<Games>>(); var rpgGame = gamesRepo.GetSingleGame(GameType.RPG);
这种写法属于服务定位器模式,只适合临时使用的特殊场景,常规业务开发还是优先用构造函数注入的方式获取依赖,不要滥用。
注意事项
- 调用前先确认已经用
using引入了扩展方法所在静态类的命名空间,这是很多人容易忽略的低级错误。 - 不要尝试直接new接口对象,
IRepository<Games>是接口类型,没有对应的实现类无法完成实例化。
内容的提问来源于stack exchange,提问作者SkyeBoniwell
相关产品推荐
相关产品推荐

