ASP.NET MVC 3.0 Internals בפוסט זה אני רוצה לכתוב על איך עובד ה- ASP.NET MVC 3.0 ואיפה אפשר להרחיב ולשנות את הטכנולוגיה.
אני מחלק את הפוסט לארבעה חלקים:
1. החיבור בין ASP.NET ל- ASP.NET MVC
2. Controller Extensibility
3. Model Extensibility
4. View Extensibility
1. החיבור בין ASP.NET ל- ASP.NET MVC.
ה- MVC חי בתוך ה- ASP.NET וכדי לשנות את סדר הפעולות שקורות ב- ASP.NET הוא משתמש במנגנון ה- Routing שנוסף בדוט-נט 4, הוא רושם אוביקט Route ל- RouteTable.

ב- Global.asax.cs אנחנו יכולים לראות את הקוד הבא:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new // Parameter defaults
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional
}
);
המתודה MapRoute היא Extension Method תפקידה ליצור אוביקט Route שמקשר בין ה- "{controller}/{action}/{id}" ל- MvcRouteHandler. אם מסתכלים בתוך הקוד של המתודה MapRoute נמצא את השורות הבאות:
var route =
new Route( url , new MvcRouteHandler() )
{ Defaults = new RouteValueDictionary(defaults),
Constraints = new RouteValueDictionary(constraints),
DataTokens = new RouteValueDictionary()
};
ה- MvcRouteHandler מממש את הממשק IRouteHandler שתפקידו לספק HttpHandler.

ה- MvcRouteHandler מחזיר מהמתודה GetHttpHandler את המחלקה MvcHandler.

התפקיד של MvcHandler ליצור מחלקה שמממשת את הממשק IControllerFactory וליצר בעזרתו את IController.

אם ברצוננו לתת מימוש אחר ל- IControllerFactory או לכל אחד מהממשקים שאני אכתוב עליהם, אנחנו יכולים לעשות את זה ע"י מימוש של IDependencyResolver ורישומו ב- Global.asax.

DependencyResolver.SetResolver( new MyDependencyResolver() );
התשתית של MVC כל פעם שהיא צריכה מימוש של ממשק היא קוראת ל- GetService ונותנת את ה-Type כארגומנט. אם אין לכם מימוש שאתם רוצים להחזיר אז מחזירים Null ואז התשתית בוחרת את מימוש ברירת המחדל של ה- MVC.
לסיכום חלק ראשון:
1. הוספנו Route אוביקט שכאשר התנאי מתקיים הוא מפעיל את GetHttpHandler מתודה של MvcRouteHandler.
2. המתודה מחזירה MvcHandler שכאשר הוא מופעל הוא פונה ל- Dependency Resolver ומבקש מימוש ל- IControllerFactory.
3. ה- IControllerFactory יוצר Controller.
2. Controller Extensibility
כאשר מדברים על נקודות הרחבה של Controller מדברים על Filters. ה- Filters מחלקים את ביצוע ה- Action לשש נקודות שאפשר להרחיב.

אפשר לשתול את ה-Filters במספר דרכים.
1. Attribute, אפשר ללהרחיב את ActionFilterAttribute.

2. לרשום אותם ישירות ל- GlobalFilters.Filters.
3. להרחיב את המחלקה Controller.

4. לממש את IFilterProvider, ולרשום את המימוש דרך FilterProvider או ע"י DependencyResolver.
3. Model Extensibility
כאן אנחנו יכולים לטפל במספר נושאים:
1. איך להמיר בקשת HTTP למחלקה של דוט-נט.
2. איך לבצע בדיקת אימות (Data Validation).
הממשק IModelBinder עושה את העבודה.

כמו שרואים ע"פ חתימת המתודה תפקידו של ממשק זה ליצר אוביקט שהוא הארגומט במתודה של ה-Action. את המידע על סוג האוביקט ועל הנתונים שהגיעו מהבקשה נמצא ב- bindingContext.

כמו שאתם רואים ה-bindingContext מספק לנו את כל המידע הרלוונטי כדי לבנות ולאתחל את האובייקט שלנו.
איך רושמים מחלקה שמממשת את הממשק IModelBinder?
1. ע"י ה-Attribute ModelBinderAttribute
2. ע"י ModelBinders.Binders
3. ע"י DependencyResolver
4. ע"י מימוש של IModelBinderProvider ורישומו דרך ModelBinderProviders או ע"י DependencyResolver.
4. View Extensibility
התפקיד של ההרחבות של ה-View הוא למצוא את המקום הפיזי של הקובץ ולהחזיר מהקובץ View מחלקה ViewEngineResult. הממשק IViewEngine אחראי על פעולות אלו.

ה-Mvc מספק שתי מימושים עיקריים לממשק זה.

אם נסתכל על RazorViewEngine המתודה CreatView יוצרת IView והמתודה FindView אורזת את ה-IView ב- ViewEngineResult.

ה-Mvc מספק גם מימושים ל-IView.

בתוך המתודה RenderView משתמשים במחלקות עזר שמממשות את הממשק IviewDataContainer.

הכל מתחיל ברישום המחלקה שמממשת את IViewEngine ע"י ViewEngines או ע"י DependencyResolver.
All the extension points:
1. Routing
a. Add Route object with IRouteHandler.
b. Custom MvcHandler
2. IDependencyResolver
3. Controller
a. IControllerFactory
b. IControllerActivator
c. IController
d. Filters
i. IAuthorizationFilter
ii. IActionFilter
iii. IResultFilter
iv. IExceptionFilter
4. Model
a. IModelBinder
b. IModelBinderProvider
c. ModelMetadataProvider
d. IValueProvider
e. ModelValidatorProvider
5. View
a. IViewEngine
b. IViewPageActivator
c. IView
d. IViewDataContainer
מקווה שעזרתי לכם להבין טוב יותר את ה-MVC ולשפר את התשתיות שתבנו. ממליץ בחום להוריד את הקוד של MVC מהאתר של CodePlex ולעבור עליו.