我的项目中有一个通用存储库。 请考虑以下控制器代码段
public class Lookup1Controller : Controller
{
readonly MyDbContext _db;
public Lookup1Controller(MyDbContext dataContext)
{
_db = dataContext;
}
public async Task<IActionResult> Index()
{
IGenericRepository<Lookup1> _repository = new GenericRepository<Lookup1>(_db);
var lookup1s = await _repository.SelectAll();
return View(lookup1s);
}
我认为不需要在我的Generic存储库以及每个控制器中都有我的数据库引用。
我将它重构为:
public class Lookup1Controller : Controller
{
private IGenericRepository<Lookup1> _repository;
public Lookup1Controller(IGenericRepository<Lookup1> repository)
{
_repository = repository;
}
public async Task<IActionResult> Index()
{
var lookup1s = await _repository.SelectAll();
return View(lookup1s);
}
}
从我读到的内容来看,它更简洁,也是ASP.NET 5的最佳实践。
但如果我在浏览器中访问该控制器路径,我将收到以下错误:
InvalidOperationException: Unable to resolve service for type 'MyProject.Data.IGenericRepository`1[MyProject.Models.Lookup1]' while attempting to activate 'MyProject.Controllers.Lookup1.
因为我没有注入GenericRepository来使用该接口。
我在Startup.cs
方法
AddScoped
ConfigureServices
行
services.AddScoped<IGenericRepository<Lookup1>,GenericRepository<Lookup1>> ();
services.AddScoped<IGenericRepository<Lookup2>,GenericRepository<Lookup2>> ();
services.AddScoped<IGenericRepository<Lookup3>,GenericRepository<Lookup3>> ();
services.AddScoped<IGenericRepository<Lookup4>,GenericRepository<Lookup4>> ();
etc
这样我的代码就可以运行而不会抛出异常。
但是我的数据库有大约100个简单的查找表。当我查看上面100行代码时,它看起来不正确。
感觉就像复制和粘贴代码一样。每次我通过添加一个新的模型和控制器添加一个新的表,我的代码将编译而不会给我一个错误。但是,如果我运行程序并转到该视图,如果我忘记将AddScoped行添加到Startup.cs
,我可能会遇到控制器运行错误。对可维护性不太好。
我的问题:
在ConfigureServices
的{{1}}方法中为每个查询表提供services.AddScoped真的是最佳做法吗?
这是一个通用的存储库,所以有没有办法在一行中写出这100个复制和粘贴行?
如果没有,那么使用我的代码执行此操作的最佳做法是什么?
答案 0 :(得分:79)
只需使用非泛型注册重载(需要传递2 Type
个对象的那些。)然后提供接口和实现的open generic types:
services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>));
在您的控制器中为特定类型的存储库添加依赖关系(封闭的泛型类型)
public HomeController(IGenericRepository<Lookup1> repository)
{
...
}
答案 1 :(得分:3)
如果您要在Assembly中注册所有IGenericRepository<>
实现:
services.AddAllGenericTypes(typeof(IGenericRepository<>), new[] {typeof(MyDbContext).GetTypeInfo().Assembly});
扩展自:
patternType