首页 > 解决方案 > C# 按实体类型自动创建存储库

问题描述

我找到了一个基于实体框架的通用存储库示例,并试图了解如何通过相同的接口和实体类型自动解析存储库。

上面的链接指向 repo,您​​可以在其中看到以下方法:

public class HomeController : Controller
{
    private readonly ICategoryRepository _repository;

    public HomeController(ICategoryRepository repository)
    {
        _repository = repository;
    }

在这种情况下,我们必须创建一个单独的 CategoryRepository - 因此,存储库是 per type

这意味着我们最终会有很多用于存储库的类。

我想远离多个类并找到一种解决方法来处理将实体类型作为类型参数传递给接口的存储库

public class HomeController : Controller
{
    private readonly IRepository<Category> _repository;

    public HomeController(IRepository<Category> repository)
    {
        _repository = repository;
    }

我试图用谷歌搜索解决方案,但在代码示例方面没有找到太多信息。

正如您从源代码中看到的那样, ASP.NET 样板框架具有此功能

我可以看到该文件夹​​中的接口文件,它们很有意义。

但是他们的实现对我来说有点模糊,因为似乎有一些额外的代码可以处理自动 repo 创建。

标签: c#entity-frameworkdependency-injectionrepository-patternioc-container

解决方案


如评论中所述,避免重新发明轮子。如果您使用任何完整的 ORM(此处为实体框架),它本身就可以用作存储库以及 UoW。因此,最推荐使用 ORM 本身内联并绕过存储库和 UoW。以下是一些不错的读物:

https://ayende.com/blog/4784/architecting-in-the-pit-of-doom-the-evils-of-the-repository-abstraction-layer

http://www.primaryobjects.com/2010/03/17/using-the-nhibernate-repository-pattern-in-c-asp-net/

但是,在某些情况下,您可能仍希望实现 Repository。这允许您在代码中注入存储库,使代码的其他部分可测试。即使在这种情况下,也要避免使用通用存储库。它被认为是一种反模式

在这种情况下,为每个聚合根实现具体的存储库。避免使用通用存储库或仅将其用作所有具体存储库的基类。更多解释可以在这个这个这个答案中找到。

您链接的 GitHub 示例代码对于 Generic Base Repository 类来说看起来不错。请注意,它暴露了IQueryable<TEntity> GetAll();. 如果在基类中实现,这应该没问题。永远不要IQueryable从您的具体存储库中返回。它违反了存储库模式的基本目的。


推荐阅读