ASP.NET Core中的通用存储库,而Startup.cs中每个表没有单独的AddScoped行?

dfm*_*tro 52 generics dependency-injection asp.net-core-mvc asp.net-core

我的项目中有一个通用存储库.请考虑以下控制器代码段

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);
    }
Run Code Online (Sandbox Code Playgroud)

我认为不需要在我的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);
    }

}
Run Code Online (Sandbox Code Playgroud)

从我读到的内容来看,它更简洁,也是ASP.NET 5的最佳实践.但如果我在浏览器中访问该控制器路径,我将收到以下错误:

InvalidOperationException: Unable to resolve service for type 'MyProject.Data.IGenericRepository`1[MyProject.Models.Lookup1]' while attempting to activate 'MyProject.Controllers.Lookup1.
Run Code Online (Sandbox Code Playgroud)

因为我没有注入GenericRepository来使用该接口.

我添加到我Startup.csAddScoped线为每一个我的表中的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
Run Code Online (Sandbox Code Playgroud)

这样我的代码就可以运行而不会抛出异常.

但是我的数据库有大约100个简单的查找表.当我查看上面的100行代码时,它看起来并不合适.

感觉就像复制和粘贴代码一样.每次我通过添加一个新的模型和控制器添加一个新的表,我的代码将编译而不会给我一个错误.但是,如果我运行该程序并转到该视图,如果我忘记将AddScoped行添加到my,我可能会出现控制器运行错误Startup.cs.对可维护性不太好.

我的问题:

  1. 是否真的是最佳做法是为ConfigureServices方法中的每个查找表提供一个services.AddScoped Startup.cs

  2. 它是一个通用的存储库,所以有没有办法在一行中写出这100个复制和粘贴行?

  3. 如果没有,那么使用我的代码执行此操作的最佳方法是什么?

Dan*_*.G. 93

只需使用非泛型注册重载(需要传递2个Type对象的那些).然后提供接口和实现的开放泛型类型:

services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>));
Run Code Online (Sandbox Code Playgroud)

在您的控制器中为特定类型的存储库添加依赖项(封闭的泛型类型)

public HomeController(IGenericRepository<Lookup1> repository)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • 如果其他人有同样的问题,我在启动应用程序时就把这个错误拉过来:无法实例化服务类型IRepo1 [T]'的实现类型Repo1 [T]'. - 这是因为我的Repo实现被标记为抽象,我能够通过简单地删除抽象声明来修复它. (7认同)
  • 这不适合我.我收到此错误:失败:Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware [0]发生了未处理的异常:尝试激活"SqlExpress.Helpers.LessonTagHelper"时无法解析类型"SqlExpress.Repository.Interfaces.IChatRepository"的服务.System.InvalidOperationException:尝试激活"SqlExpress.Helpers.LessonTagHelper"时无法解析类型"SqlExpress.Repository.Interfaces.IChatRepository"的服务.在 ... (4认同)
  • 谢谢你。更改一行代码有效。将等着看其他人是否提供意见,对于 ASP.net 5 应用程序是否是好的做法或提供替代方案 (2认同)
  • 如果它对任何人有帮助,我开始看到这一点,因为 Jetbrains Rider 建议我将 GenericRepository 构造函数从 public 更改为 protected,这是我不假思索地做的。 (2认同)