簡體   English   中英

不同領域中非常相似的控制器的最佳實踐

[英]Best practise for very similar controllers in different areas

我的asp.net MVC應用程序的區域為“公司”,區域為“管理員”。

公司可以對公司區域中的用戶執行CRUD。 我在公司區域為此創建了一個UsersController。 管理員可以在“管理員”區域中對公司用戶執行CRUD。 我在“管理”區域為此創建了一個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);
}

問題在於Admin / CompanyUsersController.cs中的Edit有一個額外的參數“ companySlug”,該參數用於查找我們當前正在為其編輯用戶的公司。 如您在上面的代碼中看到的,在Company / Userscontroller.cs中,我們只是從CurrentUser派生公司。

解決該問題的最佳方法是什么?

td; dr我有2個控制器,它們的動作同名,它們具有幾乎相同的方法主體,但參數不同。 我想盡可能地重用代碼。 請我怎么C#。

如果這兩種方法具有不同的簽名,我認為將其實現為基類方法確實不值得,盡管並非不可能。 我將在基類上創建一個受保護的幫助器方法,並將共享代碼放入其中。 像這樣(對您的Repository 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);
}

如果另一個控制器中的Edit操作具有一個額外的參數,那么我認為它不應替代基本Edit操作。 我將在派生控制器中使用兩個參數創建一個單獨的Edit操作,並使覆蓋Edit操作返回404。

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

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

由於類似的方法具有不同的參數,因此不值得實現基本控制器。 即使它們具有相同的簽名,但當着重於使控制器盡可能輕便時,代碼也將更簡潔,可讀性更高,易於理解和可維護,而不是增加太多復雜性以節省幾行重復的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM