我有一些控制器(会更多),它们分享一些行动:
public ActionResult DeleteConfirmed(int id)
{
Supplier s = db.Suppliers.Find(id);
s.Deleted = true;
db.SaveChanges();
return RedirectToAction("Index");
}
public ActionResult RestoreConfirmed(int id)
{
Supplier s = db.Suppliers.Find(id);
s.Deleted = false;
db.SaveChanges();
return RedirectToAction("Index");
}
这些行动是SuppliersController
的一部分。这样做的是,当我删除或恢复一个对象时,它将数据库中的对象标记为已删除字段的true(恢复时为false)。
许多其他控制器共享相同的行为,例如CurrenciesController
,ProductsController
等......
在我展示的代码中,您应该看到我的数据库实体已明确指定(Supplier
)以及存储库(Suppliers
)。
我想以通用的方式找到一种方法。我想创建一个自定义控制器,所有其他共享相同行为的控制器将扩展它。在这种情况下,ProductsController
会扩展我的DeleteRestoreController
。
我怎样才能以“通用”的方式做到这一点?
db
是DbContext
public partial class LE: DbContext
{
public LE()
: base("name=LE")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Category> Categories { get; set; }
public virtual DbSet<CategoryText> CategoryTexts { get; set; }
...
}
Categories
也有同样的行为。
答案 0 :(得分:1)
您可以将DeleteRestoreController
实现为抽象类。
public abstract class DeleteRestoreController : Controller
{
private IRepository : Repository;
public DeleteRestoreController() { ... }
public DeleteRestoreController(IRepository Repository) { ... }
public virtual Action DeleteConfirmed(int id)
{
Supplier s = db.Suppliers.Find(id);
s.Deleted = true;
db.SaveChanges();
return RedirectToAction("Index");
}
}
如果您需要在ProductsController
中与此行为不同,则可以简单地覆盖该方法。
public class ProductsController : DeleteRestoreController
{
public override void DeleteConfirmed()
{
//override the logic
}
}
你总是可以更进一步,实现一个通用的存储库,但我的应用程序中从未超过6-8个控制器,也没有创建过一次。
编辑我刚刚在评论中读到,实体会从控制器中的Suppliers
改变,所以如果你做的话,实现一个基本控制器没有多大意义也没有实现通用接口。罗伯特哈维在阐述复杂性必须某处时提出了一个很好的观点。
答案 1 :(得分:1)
更进一步
public abstract class DeleteRestoreController<T> : Controller
{
public virtual Action DeleteConfirmed(int id)
{
var dbset = db.Set<T>();
var s = dbset.Find(id);
s.Deleted = true;
db.SaveChanges();
return RedirectToAction("Index");
}
}
然后在定义控制器时添加实体类型
public class ProductsController : DeleteRestoreController<Supplier>
{
////blah
}