2011-03-18 102 views
3

我想重構我的基本CRUD操作,因爲它們是非常重複的,但我不確定最好的方式去實現它。我所有的控制器繼承BaseController它看起來像這樣:處理CRUD操作的MVC BaseController

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

我創造新的控制器,就像這樣:

public class ForumController : BaseController<Forum> { } 

尼斯和容易,因爲你可以看到我BaseController包含Index()方法,這樣就意味着我的控制器都有一個Index方法,並且會從存儲庫加載它們各自的視圖和數據 - 這完美地工作。我掙扎在編輯/添加/刪除方法,我在我的倉庫Add方法是這樣的:

public T Add(T Entity) 
{ 
    Table.AddObject(Entity); 
    SaveChanges(); 

    return Entity; 
} 

同樣,好和容易的,但在我的BaseController我顯然無法做到:

public ActionResult Create(Category Category) 
{ 
    Repository.Add(Category); 
    return RedirectToAction("View", "Category", new { id = Category.Id }); 
} 

正如我通常會這樣:任何想法?我的大腦似乎無法獲得通過該..; -/

回答

2

你可以通過添加所有實體共享的接口:

public interface IEntity 
{ 
    long ID { get; set; } 
} 

,讓您的基本控制器需要這樣的:

public class BaseController<T> : Controller where T : class, IEntity 

這將允許您:

public ActionResult Create(T entity) 
{ 
    Repository.Add(entity); 
    return RedirectToAction("View", typeof(T).Name, new { ID = entity.ID }); 
} 

你也應該考慮使用依賴注入實例你r控制器,以便您的存儲庫被注入而不是手動實例化,但這是一個單獨的主題。

+0

我試過這個,但它似乎沒有工作;我得到編譯器錯誤,如'錯誤類型'Models.Category'不能用作通用類型或方法'Controllers.BaseController '中的類型參數'T'。沒有從'Models.Category'到'System.Data.Objects.DataClasses.EntityObject'的隱式引用轉換。'和'錯誤\t'Models.User'類型不能用作類型參數'T'泛型類型或方法'控制器。BaseController '。沒有從'Models.User'到'Classes.Core.IEntity'的隱式引用轉換。' 我正在使用EF4。 – eth0 2011-03-18 22:45:33

+0

你需要讓你的實體實現IEntity。也就是說,定義「class Category:IEntity」並在其上實現ID屬性。 – 2011-03-18 22:47:17

+0

如果您使用的是EF,那麼最好的方法是添加一個「public partial class Category:IEntity」部分類並添加ID屬性。一定要在與實體類相同的名稱空間中定義它。 – 2011-03-18 22:49:07

0

不知道是什麼問題,你不能讓CRUD點也是通用的?

public virtual ActionResult Create(T entity) where T : IEntity 
{ 
    Repository.Add(entity); 
    return RedirectToAction("View", this.ModelType, new { id = entity.Id }); 
} 

這假定:

  • 你的控制器設置它們構造時,被稱爲「ModelType」基地控制器上的值,告訴它什麼樣「的車型,它應該被控制。
  • 您有一個通用接口(IEntity)或已知的基類,它具有一組基本屬性(如Id),控制器可以使用它們來管理流參數等。

我實際上沒有嘗試過這個,但是我已經完成了與它相似的腳手架,並且該模式工作得很好。如果無法修改或擴展您的POCO(或任何您使用的)對象模型,它可能會變得粘稠。