如何删除存储库中的代码冗余

时间:2020-04-10 08:30:33

标签: c# interface polymorphism redundancy

目前,我的数据库中有2个表。膳食和餐桌(这是餐厅管理应用程序)。我已经为两个表创建了存储库接口及其实现(授权用户应该能够添加/删除/更新进餐和当菜单中出现新进餐时的表数据)。 问题是我的两个接口都具有基本上相同的方法,这导致了我相信的代码冗余。这些是我的界面:

public interface IMealsRepository
{
    IEnumerable<Meal> FindAll();
    Meal FindById(int id);
    Meal FindByName(string mealName);
    Meal AddMeal(MealDTO newMeal);
    void RemoveMeal(int id);
    Meal UpdateMeal(Meal meal);
}

public interface ITablesRepository
{
    IEnumerable<Table> FindAll();
    Table FindById(int id);
    Table AddTable(Table newTable);
    void RemoveTable(int id);
    Table UpdateTable(Table table);
}

我尝试使用FindAll,FindById,Add,Remove,Update的常用方法制作基本存储库接口,但遇到了我要获取并返回不同类型的问题,例如对于Add方法,我将根据接口返回Table对象或Meal对象。我尝试使用对象方法:

public interface IRepository
{
    IEnumerable<object> FindAll();
    object FindById(int id);
    object Add(object newObject);
    void Remove(int id);
    object Update(object updatedObject);
}

然后,我只需要IMealsRepository:IRepository和ITablesRepository:IRepository并添加这些存储库唯一的其他方法,例如按名称搜索Meal。我的餐食界面如下所示:

public interface IMealsRepository : IRepository
{
    Meal FindByName(string mealName);
}

我还为那些存储库提供服务,这是唯一能够访问存储库并使用存储库方法返回那些特定类型的对象的服务。这是个好方法吗?或者我在这个项目中对我的存储库的接口太过深入了?

2 个答案:

答案 0 :(得分:2)

您可以遵循此link来实现泛型/基本存储库(如果您不使用Entity Framework / SQL,仍然有效)。

除了基本/通用存储库模式之外,您还需要考虑一些其他事项

  1. 在多个存储库中进行操作时,请使用UnitOfWork模式来维护事务。

  2. 不为每个表/域对象创建存储库。仅为聚合对象创建存储库(在电子商务上下文中,示例为Order,而不是OrderDetail)。

  3. 如果不需要,请不要创建表/域特定的存储库。如果您正在执行简单的CRUD操作,并且基本存储库中已经存在所有类型的操作,那么您就不需要特定于表的存储库

    公共类AdvertisementService:IAdvertisementService { 私有只读IBaseRepository imageRepository;

    public AdvertisementService(
        IBaseRepository<AdvertisementImage> imageRepository)
    {
    
        this.imageRepository = imageRepository;
    }
    

Startup.cs

builder.Services.AddScoped<IBaseRepository<AdvertisementImage>, BaseRepository<AdvertisementImage>>();

在上面的示例中,我没有创建任何“ AdvertisementImage”存储库。

答案 1 :(得分:1)

此类问题可以使用.NET泛型来解决。泛型允许您创建类似RepositoryBase<T>的类和类似IRepository<T>的接口

“ T”是您在继承类或实现接口中指定的对象的类型。

使用泛型,您可以创建如下界面:

public interface IRepository<T>
{
    IEnumerable<T> FindAll();
    T FindById(int id);
    T Add(T newObject);
    void Remove(int id);
    T Update(T updatedObject);
}

或者像这样的基类:

public abstract class RepositoryBase<T, TDto> : IRepository<T>
{
    protected IEnumerable<T> FindAll() { // your implementation logic}
    protected T FindById(int id) { // your implementation logic
    protected T FindByName(string mealName) { // your implementation logic
    protected T AddMeal(TDto newMeal) { // your implementation logic
    protected void RemoveMeal(int id) { // your implementation logic
    protected T UpdateMeal(Meal meal) { // your implementation logic
}

Internet上有很多有关泛型的信息,但是我很确定泛型是您在这种情况下要使用的。