通用 C# 存储库、服务和控制器设计

Generic C# Repository, service and controller design

我正在学习泛型,想知道泛型控制器、服务和 ef 核心存储库设计会是什么样子。

我的情况:假设有一个传入的 post 请求将智能手机和键盘对象添加到智能手机和键盘表

我的存储库设置是

    public class GenericRepository<TEntity> : IGenericRepository<TEntity>
                where TEntity : class, IProductGenericEntities
{
    private readonly MyDbContext _db;
    public GenericRepository(MyDbContext db)
    {
        _db = db;
    }

    public async Task<bool> AddProduct(TEntity entity)
    {
        try
        {
            _db.Set<TEntity>().AddAsync(entity);
            return (await _db.SaveChangesAsync()) > 0;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return false;
        }
    }
}

还有我的服务

    public class ProductService<TEntity> : IProductService<TEntity>
            where TEntity : class
{
    private readonly IGenericRepository<TEntity> _repo;

    public ProductService(IGenericRepository<TEntity> repo)
    {
        _repo = repo;
    }


    public async Task<bool> AddProduct(TEntity entity)
    {
        return await _repo.AddProduct(entity);
    }

}

还有我的Controller.cs

    [ApiController]
[Route("api/[controller]")]
public class ProductController
{
    private readonly IProductService<Keyboards> _keyService;
    private readonly IProductService<Smartphones> _smartService;

    public ProductController(IProductService<Keyboards> keyService, IProductService<Smartphones> smartService)
    {
        _keyService = keyService;
        _smartService = smartService;
    }

    [HttpPost("Post-generated-items")]
    public async Task<ActionResult> PostProducts(List<TEntity> entities)
    {
        foreach(var item in entities)
        {
            and sort the objects here
        }
        
    }
}

初始化 2 个 IProductServices 并将传入对象排序到控制器上正确的 DI 是否正确?

    private readonly IProductService<Keyboards> _keyService;
private readonly IProductService<Smartphones> _smartService;

有没有一种方法可以通过检测传入的对象类型使其更加自动化,然后将其一直初始化到 repo,这样我就不需要 2 个 IProductService<>?

还是我在通用服务层上做错了什么?

好的,所以你的方法是完全有效的,我不会担心初始化两个存储库,因为它们本质上是空的内存虎钳,因为它们只是引用现有的 DbContext,默认情况下注册到 范围 生命周期。

有时您需要使用多个存储库来完成手头的任务。我建议采用 NON-generic 服务方法。通过这种方式,您可以使 ProductsService 注入所有需要的通用存储库,并可以编排它们的工作以实现用例目标。

您不妨研究 UOW(工作单元)模式以应对更复杂的情况。

回答您的问题:

Is there a way to make it more automatic by detecting incomming object type and then initilize it all the way to repo so i dont need 2 of IProductService<>?

您可能会编写一些代码来使用反射为您完成此操作,但我建议您不要这样做。通过专门初始化您的存储库,您可以减少自己出错的可能性,并且代码变得更多 self-documenting.

例如,现在您有一个控制器,它向 DI 请求两项服务,并立即让您了解该控制器中发生的事情。另一方面,如果一切都是通用的,你最终会得到一个“什么都做”的意大利面条大结。