我试图实施这种机制:
模型具有位字段:is_active
,因此我使用它来切换主窗体上的可见性。控制器中的动作如下:
public ActionResult Toggle(int id)
{
Country country = _db.Countries.Find(id);
country.is_active = country.is_active == null ? true : !country.is_active;
_db.SaveChanges();
return RedirectToAction("Index");
}
我希望我的管理查找控制器从该泛型类派生,并使用它的实现来执行常见操作,如切换。
我已经创建了ActionResult Toggle(int id)
的ITogglable接口,所以我在特定的控制器(CountryController : Controller, ITogglable
)中实现它,但我必须每次都实现它。相反,我更喜欢我的CountryController,RegionController等派生自通用类(即Togglable
),这些类已经实现了这样的方法:
public virtual ActionResult Toggle(int id)
{
CurrentModelTypeUsedInController lookup = _db.CurrentModelTypeUsedInController.Find(id);
lookup .is_active = lookup .is_active == null ? true : !lookup.is_active;
_db.SaveChanges();
return RedirectToAction("Index");
}
这甚至可能吗?我不知道如何使它与查询无关,所以我不必每次都提供CurrentModelTypeUsedInController
的类型。
答案 0 :(得分:3)
您需要一些抽象来实现这一目标。
首先,您需要一个定义is_active
的抽象,例如
public interface IActive
{
bool is_active { get; set; }
}
所有类型如Country
和CurrentModelTypeUsedInController
都需要实现此抽象
public class Country : IActive
{
public bool is_active { get; set; }
}
有了这个,我们定义了通用控制器。这里的关键点是放置在泛型(IActive
)上的泛型约束(TModelType
)。通过定义所有类型的TModelType
必须实现IActive
,代码知道该类型保证公开名为is_active
的属性
public class AbstractController<TModelType> : Controller
where TModelType : class, IActive
{
private readonly DbContext _db;
public AbstractController()
{
_db = new DbContext("connection");
}
public ActionResult Toggle(int id)
{
TModelType instance = _db.Set<TModelType>().Find(id);
instance.is_active = instance.is_active == null ? true : !instance.is_active;
_db.SaveChanges();
return RedirectToAction("Index");
}
}
每个控制器都可以从AbstractController<>
public sealed class CountryController : AbstractController<Country>
{
}