繼承技巧:BaseController與BaseApiController
BaseController與BaseApiController類別技巧不算是ASP.NET MVC或ASP.NET Web API的技術,它是一個OOP(Object-oriented programming,物件導向程式設計)繼承的應用,這在早期Web Forms就已經被大量使用,因為它只是單純的OOP繼承應用,並不會被語言或框架所限制。
ASP.NET MVC - Controller類別
我們先來看看我們在進行開發的Controller類別繼承關係:
ControllerBase類別繼承自IController介面,Controller類別繼承自ControllerBase類別,而ControllerBase與Controller都是抽象類別:
public abstract class ControllerBase : IController {} public abstract class Controller : ControllerBase, IActionFilter, IAuthenticationFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter, IAsyncController, IAsyncManagerContainer {}
而我們開發者所在的ASP.NET MVC的Controller都是繼承自Controller抽象類別,Controller抽象類別提供開發者所需的大部分功能:
public class HomeController : Controller {}
從程式設計的角度來看,ASP.NET MVC的Controller也只是一個類別。如果你發現自己在其他Controller寫了完全相同邏輯的程式碼(相同的成員、屬性或方法等),那麼我們有非常合理的理由來建立一個共用的基礎類別,之後將Controller裡相同的成員、屬性或方法往上層的基礎類別移動,Controller只需重新繼承此基礎類別,就能發揮物件導向的繼承的優勢。
BaseController是繼承自Controller的類別,用於集中共用程式碼讓底下實作的Controller繼承使用。
BaseController - 資料庫物件初始化
以Northwind資料庫為例,使用基架多產生幾個Controller類別(ProductsController、OrdersController、OrderDetailsController…),分析這些所有Controller類別會發現有一個成員會不斷重覆出現在所有的Controller類別中:
private NorthwindEntities db = new NorthwindEntities();
這裡不討論Repository模式或IoC的應用。
新增一個BaseController類別並繼承Controller抽象類別,然後將產生db執行個體的程式碼移至BaseController類別:
public class BaseController : Controller { protected NorthwindEntities db = new NorthwindEntities(); }
注意,為了讓子類別可以存取,存取修飾詞不能是private。修改MVC Controller所繼承的類別(以ProductsController為例):
public class ProductsController : BaseController { // 可刪除。註解是為讓讀者瞭解。 // private NorthwindEntities db = new NorthwindEntities(); }
BaseController - 指定Title
基架系統產生的View Page,每一頁面的title值是在View Page裡去指定,當要一一指定每一個頁面title值時非常不便(你要開啟每一個Action方法對應的View Page再一一修改)。
@{ ViewBag.Title = "Index"; }
我們希望直接在Action方法裡去指定title的值。把View Page裡的指定title的程式碼刪除,然後在BaseController裡新增一個Title屬性:
public class BaseController : Controller { protected NorthwindEntities db = new NorthwindEntities(); // 新增Title屬性 protected string Title { set { ViewBag.Title = value; } } }
在繼承BaseController類別的MVC Controller類別中就能直接進行title的設置:
public class ProductsController : BaseCont { public ActionResult Index() { // 指定Title屬性 Title = "產品首頁"; return View(db.Products.ToList()); } // 省略 }
如果你有些專屬於此系列MVC Controller的Action Filters,也能在BaseController裡去覆寫(Override)而繼承的MVC Controller會直接生效。
public class BaseController : Controller { // 覆寫ActionFilters protected override void OnActionExecuting(ActionExecutingContext filterContext) { log("OnActionExecuting", filterContext.RouteData); } private void log(string method, RouteData routeData) { // Log程式碼 } }
Action Filters本身是一種AOP 設計,在BaseController類別裡覆寫Action Filters的方式並不是很好的方式。這裡要清楚類別繼承的應用情境與AOP的應用情境是不同的。
BaseApiController
在ASP.NET Web API 2裡的應用等同於Web Form與ASP.NET MVC的應用方式,新增BaseApiController並繼承ApiController,然後實作共用程式碼,並讓其他子ApiController繼承BaseApiController。
public class BaseApiController : ApiController { // 共用程式碼 }
沒有留言:
張貼留言
感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。