【问题标题】:How to remove code redundancy in repositories如何删除存储库中的代码冗余
【发布时间】:2020-04-10 08:30:33
【问题描述】:

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

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);
}

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

【问题讨论】:

    标签: c# interface polymorphism redundancy


    【解决方案1】:

    您可以按照这个link 来实现Generic/Base Repository(如果您没有使用Entity Framework/SQL,这仍然有效)。

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

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

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

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

      公共类广告服务:IAdvertisementService { 私有只读 IBaseRepository imageRepository;

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

    Startup.cs

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

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

    【讨论】:

      【解决方案2】:

      此类问题可以通过 .NET 泛型解决。泛型允许您创建像 RepositoryBase&lt;T&gt; 这样的类和像 IRepository&lt;T&gt; 这样的接口

      “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
      }
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-08-02
        • 2021-02-21
        • 2010-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-02
        相关资源
        最近更新 更多