2013-11-27 16 views
2

我的asp.net MVC應用程序有一個區域「公司」和一個區域「管理員」。在不同地區非常相似的控制器的最佳實踐

公司可以在公司區域的用戶上做CRUD。我在公司區域爲此創建了一個UsersController。 管理員可以在管理員區域的公司用戶上執行CRUD。我在Admin區域爲此創建了一個CompanyUsersControllers。

這兩個控制器都有非常相似的代碼,我想知道什麼最乾淨的方法是重用大部分代碼。

在寫這個問題時,我想我可以用虛擬ActionResults創建一個抽象的UsersControllerBase類。我這樣做,它適用於公司地區。我在UsersController類的重寫方法上定義屬性,並在每個重寫方法中調用相應的抽象方法。

這裏是從基類的例子:

[UsersControllerBase.cs] 
public virtual ActionResult Edit(string slug) 
{ 
    var user = UserRepository.GetBySlug(slug); 

    if (user.CompanyId != CurrentUser.CompanyId) 
    { 
     throw new SecurityException(CurrentUser.Id + " attempted to edit a user that does not belong to his company"); 
    } 

    var model = user.ToViewModel(); 
    AddListsTo(model); 

    return View(model); 
} 

以及相應的控制裝置:

[Company/UsersController.cs] 
[HttpGet, GET("/company/users/{slug}/edit")] 
public override ActionResult Edit(string slug) 
{ 
    return base.Edit(slug); 
} 

的問題是,在管理/ CompanyUsersController.cs編輯有一個額外的參數「companySlug 「這是用來找到我們目前正在編輯用戶的公司。 正如您在上面的代碼中看到的,在Company/Userscontroller.cs中,我們只需從CurrentUser派生出公司。

什麼是最好的方法來處理這個問題?

td; dr 我有2個控制器具有名稱相同的動作,它們具有接近相同的方法體但參數不同。我想盡可能重用代碼。請問我如何c#。

回答

3

如果這兩種方法有不同的簽名,我認爲它並不值得將其作爲基類方法實現,儘管這不是不可能的。我會在基類上創建一個受保護的幫助器方法,並將共享代碼放入其中。像這樣(做你的庫API一些假設):

[UsersControllerBase.cs] 
protected virtual ActionResult Edit(User user) 
{ 
    var model = user.ToViewModel(); 
    AddListsTo(model); 

    return View(model); 
} 

[Admin/CompanyUsersController.cs] 
[HttpGet, GET("/admin/users/{companySlug}/{slug}/edit")] 
public ActionResult Edit(string companySlug, string slug) 
{ 
    var user = UserRepository.GetBySlug(companySlug, slug); 
    return base.Edit(user); 
} 

[Company/UsersController.cs] 
[HttpGet, GET("/company/users/{slug}/edit")] 
public ActionResult Edit(string slug) 
{ 
    var user = UserRepository.GetBySlug(slug); 

    if (user.CompanyId != CurrentUser.CompanyId) 
    { 
     throw new SecurityException(CurrentUser.Id + " attempted to edit a user that does not belong to his company"); 
    }   
    return base.Edit(user); 
} 
+0

我會放棄我認爲的想法..這似乎不值得。我可以嘗試通過使控制器更輕量一些來重用某些部件。感謝您的回覆! –

1

如果其他控制器的編輯操作有一個額外的參數,那麼它不應該是基本編輯操作的重寫,在我看來, 。我會創造派生控制器獨立的編輯操作有兩個參數,並進行覆蓋編輯行動回報404

[HttpGet] 
public override ActionResult Edit(string slug) 
{ 
    return HttpNotFound(); 
} 

[HttpGet] 
public ActionResult Edit(string slug, string companySlug) 
{ 
    // some code... 
} 
0

,因爲類似的方法有不同的參數不值得實施basecontroller。 即使它們具有相同的簽名,當專注於保持控制器儘可能輕量級,而不是增加太多複雜度以節省一些重複代碼行時,代碼更清晰,更易讀,易於理解和維護。