Reputation: 5137
I want to refactor my basic CRUD operations as they are very repetitive but I'm not sure the best way to go about it. All of my controllers inherit BaseController which looks like so:
public class BaseController<T> : Controller where T : EntityObject
{
protected Repository<T> Repository;
public BaseController()
{
Repository = new Repository<T>(new Models.DatabaseContextContainer());
}
public virtual ActionResult Index()
{
return View(Repository.Get());
}
}
I create new controllers like so:
public class ForumController : BaseController<Forum> { }
Nice and easy and as you can see my BaseController
contains an Index()
method so that means my controllers all have an Index method and will load their respective views and data from the repository - this works perfectly. I'm struggling on Edit/Add/Delete methods, my Add
method in my repository looks like this:
public T Add(T Entity)
{
Table.AddObject(Entity);
SaveChanges();
return Entity;
}
Again, nice and easy but in my BaseController
I obviously can't do:
public ActionResult Create(Category Category)
{
Repository.Add(Category);
return RedirectToAction("View", "Category", new { id = Category.Id });
}
as I usually would so: any ideas? My brain can't seem to get pass this.. ;-/
Upvotes: 4
Views: 3087
Reputation: 16651
Not sure what the problem is, you can't make the CRUD points to be generic as well?
public virtual ActionResult Create(T entity) where T : IEntity
{
Repository.Add(entity);
return RedirectToAction("View", this.ModelType, new { id = entity.Id });
}
This assumes that:
IEntity
) or known base class which has a set of basic properties (like Id
) which can be used by the controller to manage flow parameters and so on.I haven't actually tried this but I've done scaffolding similar to it and the pattern works well enough. It might be sticky if it's not possible to modify or extend your POCO (or whatever you're using) object model.
Upvotes: 0
Reputation: 9474
You could add an interface shared by all entities:
public interface IEntity
{
long ID { get; set; }
}
And make your base controller require this:
public class BaseController<T> : Controller where T : class, IEntity
Which would allow you to:
public ActionResult Create(T entity)
{
Repository.Add(entity);
return RedirectToAction("View", typeof(T).Name, new { ID = entity.ID });
}
You should also consider using dependency injection to instantiate your controllers, so that your repositories are injected rather than instantiated manually, but that is a separate topic.
Upvotes: 2