Eldar
Eldar

Reputation: 872

How can I share same action logic between controllers with respect the repository pattern

I have CompanyController and 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");
   }
}

You can see that logic of BatchDelete is the same and I want it place to parent controller, but there is a challenge, the repository. I cant call in base controller repository.GetList().

Upvotes: 1

Views: 579

Answers (2)

Steve Michelotti
Steve Michelotti

Reputation: 5213

You have to have some commonality in your repository interface. For example, you could this do:

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

where you have:

public interface ICompanyRepository : IRepository<T>

and

public interface IDepartmentRepository : IRepository<T>

Then you can set up your base controller like this:

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

UPDATE Then your CompanyController will look like this:

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

This will do the trick.

One other note of caution it looks like your GetList() is getting all entites from the database and then select the one you want to delete for the delete operation. Better to retrieve only the one you are interested from the database and save significant performance.

Upvotes: 2

Wyatt Barnett
Wyatt Barnett

Reputation: 15663

This, children, is why we pass services to Controllers, not raw repositories.

Upvotes: 1

Related Questions