ASP.NET MVC, Entity Framework: Generic model-independent controller class implemented with actions

若如初见. 提交于 2019-12-12 04:14:25

问题


I'm trying to implement this kind of mechanizm:

Model has bit field: is_active, so I'm using it to toggle visibility on the main form. The action in controler is like:

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

I want my admin lookup controllers to derive from that generic class and use the implementation from it for common actions like toggle.

I've already created ITogglable interface that has ActionResult Toggle(int id) so I'm implementing it inside particular controler (CountryController : Controller, ITogglable), but I have to implement it every time. Instead I would more like my CountryController, RegionController, etc derive from a generic class (i.e. Togglable) that has these kind of methods already implemented like:

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

Is this even possible? I have no idea how to make it lookup-independant so I do not have to provide type of CurrentModelTypeUsedInController each time.


回答1:


You need a couple of abstractions to achieve this.

Firstly you will need an abstraction that defines is_active, such as

public interface IActive 
{ 
    bool is_active { get; set; } 
}

And all of the types such as Country and CurrentModelTypeUsedInController will need to implement this abstraction

public class Country : IActive 
{
    public bool is_active { get; set; }
}

And with this in place we define the generic controller. The key point here is the generic constraint (IActive) that is placed on generic type (TModelType). By defining that all types of TModelType must implement IActive the code knows that the type is guaranteed to expose a property named 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");
    }
}

And each controller can derive from AbstractController<>

public sealed class CountryController : AbstractController<Country>
{
}


来源:https://stackoverflow.com/questions/24755523/asp-net-mvc-entity-framework-generic-model-independent-controller-class-implem

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!