【问题标题】:How can I share same action logic between controllers with respect the repository pattern关于存储库模式,我如何在控制器之间共享相同的操作逻辑
【发布时间】:2010-10-22 16:18:56
【问题描述】:

我有 CompanyController 和 DepartmentController:

public class CompanyController : BaseBackendController
{
   private ICompanyRepository repository;
   public CompanyController(ICompanyRepository repository)
   {
     this.repository = repository;
   }

  ...
   [HttpPost]
   public ActionResult BatchDelete(long[] ids)
   {

     var entities = repository.GetList().Where(item => ids.Contains(item.ID));

     repository.BatchDelete(entities);
     return RedirectToAction("Index");
   }
}

public class DepartmentController : BaseBackendController
{
   private IDepartmentRepository repository;
   public DepartmentController(IDepartmentRepository repository)
   {
     this.repository = repository;
   }

  ...
   [HttpPost]
   public ActionResult BatchDelete(long[] ids)
   {

     var entities = repository.GetList().Where(item => ids.Contains(item.ID));

     repository.BatchDelete(entities);
     return RedirectToAction("Index");
   }
}

您可以看到 BatchDelete 的逻辑是相同的,我希望将它放置到父控制器,但是有一个挑战,存储库。我无法调用基本控制器 repository.GetList()。

【问题讨论】:

    标签: asp.net-mvc linq-to-sql repository-pattern


    【解决方案1】:

    您必须在存储库界面中具有一些共性。例如,您可以这样做:

    public interface IRepository<T>
    {
        IEnumerable<T> GetList();
        void DeleteBatch(IEnumerable<T> entities);
        // other methods here
    }
    

    你在哪里:

    public interface ICompanyRepository : IRepository<T>
    

    和

    public interface IDepartmentRepository : IRepository<T>
    

    然后你可以像这样设置你的基本控制器:

    public abstract class DataController<TModel> : Controller
    {
        protected IRepository<TModel> repository;
    
        public DataController(IRepository<TModel> repository)
        {
            this.repository = repository;
        }
    
       [HttpPost]
       public ActionResult BatchDelete(long[] ids)
       {
    
         var entities = repository.GetList().Where(item => ids.Contains(item.ID));
    
         repository.BatchDelete(entities);
         return RedirectToAction("Index");
       }
    }
    

    更新然后您的 CompanyController 将如下所示:

    public CompanyController : DataController<Company>
    {
        public CompanyController(IRepository<Company> repository) : base(repository)
        {
        }
    }
    

    这样就可以了。

    另一个注意事项,您的 GetList() 似乎正在从数据库中获取 all 实体,然后选择要删除的实体以进行删除操作。最好仅从数据库中检索您感兴趣的那一项,从而显着节省性能。

    【讨论】:

    • 不错!但我怀疑 CompanyController ctor 的外观如何?
    • 我也用 CompanyController 的代码更新了上述答案。
    • 如果我在 ICompanyRepository 中有特定的方法。如何从 CompanyController 调用它?我不想在 IRepostiory 中声明它
    • 到之前的评论:如果我在控制器“private new ICompanyRepository repository;”中明确隐藏存储库字段,它将起作用
    • 不要将其设为“私有新” - 而是将范围设为“受保护”而不是“私有”基本控制器。这将允许您从 CompanyController 访问特定于此存储库的那些方法。
    【解决方案2】:

    孩子们,这就是我们将服务传递给控制器​​而不是原始存储库的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-05
      • 2020-12-22
      • 2023-03-25
      • 1970-01-01
      • 2017-12-19
      • 1970-01-01
      • 2017-01-03
      相关资源
      最近更新 更多