通用 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 请求两项服务,并立即让您了解该控制器中发生的事情。另一方面,如果一切都是通用的,你最终会得到一个“什么都做”的意大利面条大结。
我正在学习泛型,想知道泛型控制器、服务和 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 请求两项服务,并立即让您了解该控制器中发生的事情。另一方面,如果一切都是通用的,你最终会得到一个“什么都做”的意大利面条大结。