Präsentation herunterladen
Die Präsentation wird geladen. Bitte warten
1
ASP.NET MVC Stefan Lieser Email: stefan@lieser-online.destefan@lieser-online.de Web: http://www.lieser-online.dehttp://www.lieser-online.de
2
WAS IST LEGACY CODE?
3
Code ohne Tests ist Legacy Code
4
Michael Feathers Code without tests is bad code. It doesn't matter how well written it is; it doesn't matter how pretty or object-oriented or well-encapsulated it is. With tests, we can change the behavior of our code quickly and verifiably. Without them, we really don't know if our code is getting better or worse.
5
Agenda Einführung MVC Pattern Routing Dependency Injection Tests Controller, View, Routing
6
Einführung Ziele Funktionsweise Was ändert sich gegenüber WebForms?
7
Einführung Erste Präsentation durch Scott Guthrie ALT.NET Conference Oktober 2007 Austin http://www.hanselman.com/silverlight/ScottGuAtAltnetConf/ http://www.hanselman.com/silverlight/ScottGuAtAltnetConf/ Bisher CTP1, CTP2, Source Drop, sozusagen pre-CTP3
8
Ziele Testability Interfaces, abstract base classes (Mock Objects) Designed with TDD in mind Extensibility Keine sealed classes Pluggability z.B. Austausch der ViewEngine
9
Einführung Map URL to Class Front Controller
10
Einführung Basierend auf ASP.NET Standard ViewEngine verwendet.aspx, MasterPages und CSS Kein PostBack Kein ViewState Kein WebForms Keine UserControls Kein ASP.NET AJAX
11
Auf Wiedersehen
12
Ok, jetzt gehts los
13
Verwendete Komponenten ASP.NET MVC (Microsoft) http://www.codeplex.com/aspnet MVCContrib (Community) http://www.codeplex.com/MVCContrib Castle Windsor http://www.castleproject.org/container/
14
Verwendete Komponenten Rhino.Mocks http://www.ayende.com/projects/rhino-mocks.aspx NUnit http://www.nunit.org ReSharper 4.0 http://www.jetbrains.com/resharper/ http://www.jetbrains.net/confluence/display/ReSharp er/ReSharper+4.0+Nightly+Builds http://www.jetbrains.net/confluence/display/ReSharp er/ReSharper+4.0+Nightly+Builds
15
Model View Controller und andere Patterns
16
Model View Controller Ziele Entkopplung Separation of concerns Single responsibility principle Model: enthält die Daten View: präsentiert die Daten Controller: vermittelt zwischen Model und View
17
Abgrenzung zu MVP MVP geht weiter als MVC MVC Model: nicht zwangsläufig ein Business Domain Modell sondern häufig ein Application Modell
18
MVC Varianten Front Controller Supervising Controller Passive View
19
Routing http://localhost/was/kommt/jetzt http://localhost/was/kommt/jetzt Wie wird eine URL interpretiert?
20
Routing ASP.NET WebForms
21
Routing ASP.NET MVC public class ShopController : Controller { public RenderViewResult Artikel(string id) { Artikel artikel = repository.Get(id); return RenderView("Artikel", artikel); }
22
Der Unterschied ASP.NET WebForms View first ASP.NET MVC Controller first
23
Routing ASP.NET MVC Keine fixe Zuordnung von URL zu Verzeichnissen und Dateien Stattdessen bestimmen Routingregeln wie eine URL auf Controller und Action abgebildet wird. Routing Tabelle wird in Global.asax initialisiert. System.Web.Routing ist Bestandteil des.NET Framework 3.5 SP1
24
Routing Map routes.MapRoute( "Default", "{controller}/{action}/{id}, new { controller = "Home", action = "Index", id = "" }, new { controller = @"[^\.]*" } ); Name URL mit Parametern Parameter Defaults Parameter Constraints
25
Controller, Action und Parameter {controller}/{action}/{id} URL -> Routing -> Controller.Action(…) /Backlog/Item/5 public class BacklogController : Controller { public RenderViewResult Item(string id) { BacklogItem item = repository.Get(id); return RenderView("Item", item); }
26
Routing /Blogs BlogsController.List("Lieser", "01.01.2008", "") /Blogs/Meier/05.07.2006/ein-artikel BlogsController.List("Meier", "05.07.2006", "") routes.MapRoute( "Blogs", "Blogs/{username}/{date}/{article}", new { controller = "Blogs", action="List", username = "Lieser", date = "01.01.2008", article = "" } );
27
Routing Signatur MapRoute: (string name, string url, object defaults, object constraints) Warum sind defaults und constraints vom Typ object ? Parameter!! Beachte den anonymen Typ! new { controller = "…", action = "…", myParameter = "42" } controller und action müssen vorhanden sein, sonst Laufzeitfehler.
28
Routing Demo Ändern der Routing Map BlogsController
29
Routing rückwärts Erzeugen einer URL aus Controller und Action: Erzeugt die URL /Backlog/Add gemäß der Routingregel DRY – Dont repeat yourself Refactoring Intellisense ( a => a.Add(), "Hinzufügen")%>
30
Controller
31
Implementiert IController Alle public methods sind Actions [NonAction] verhindert das Jede Action liefert ein ActionResult zurück Das ActionResult bestimmt was als nächstes passiert
32
Vom Controller zum View Controller Action liefert ein ActionResult ExecuteResult(ControllerContext context) wird aufgerufen und rendert den View. public BacklogController : Controller { public ActionResult Index() { return RenderView("Index"); }
33
RenderView Verzeichnisstruktur bei RenderViewResult
34
ViewData ViewPage Property ViewData vom Typ T ViewPage ViewData vom Typ System.Web.Mvc.ViewData Dictionary: ViewData["Artikel"] = artikel
35
ViewData verwenden Backlog Item Id: Name: public BacklogController : Controller { public ActionResult Index() { BacklogItem backlogItem = … return RenderView("Index", backlogItem); }
36
Vom View zum Controller
37
Form Führt zu folgendem Methodenaufruf: BacklogController.Save(string name) <input type="text" name="name" id="name value=" " /> <input type="submit" value="Ok" name="submit id="submit" />
38
Form mit Html Helper
39
Tests Model Routing Controller View
40
Routing Tests GetHttpContext ist eine Helper Methode (siehe Demo) using (mocks.Record()) { context = GetHttpContext(mocks, "~/Backlog/List"); } using (mocks.Playback()) { RouteData routeData = routes.GetRouteData(context); Assert.That(routeData.Values["Controller"], Is.EqualTo("Backlog")); Assert.That(routeData.Values["Action"], Is.EqualTo("List")); }
41
Controller Tests ActionResult der Actions können gut getestet werden RenderViewResult renderViewResult = backlogController.List(); Assert.That(renderViewResult.ViewName, Is.EqualTo("List")); Assert.That(renderViewResult.ViewData, Is.TypeOf(typeof(BacklogViewData))); Assert.That(((IViewData)renderViewResult.ViewData).ErrorMessage, Is.EqualTo(expectedErrorMessage));
42
View Tests Im View steckt Code! -> Unit Tests ASP.NET Engine erforderlich um einen View zu rendern Bislang keine explizite Unterstützung für View Tests Integrationstest z.B. mit WatiN möglich
43
Alternative View Engines Im MVCContrib Projekt: Brail NVelocity NHaml Xslt
44
Dependency Injection
45
Controller benötigt Repository public class BacklogController : Controller { private IRepository m_Repository; public BacklogController(IRepository repository) { m_Repsitory = repository; } public RenderViewResult Show(string id) { Backlog backlog = m_Repository.Get(id); return RenderViewResult("Show", backlog); }
46
Dependency Injection (DI) ASP.NET MVC unterstützt den Einsatz beliebiger IoC Container zur Dependency Injection. Vorteil der Dependency Injection: die Konstruktoren der Controller können Parameter erhalten um darüber die Abhängigkeiten zu definieren. ControllerBuilder.Current.SetControllerFactory(...)
47
MvcContrib Bietet Factories für Castle Windsor StructureMap Spring.NET ObjectBuilder Unity NInject
48
DI am Beispiel Castle Windsor Zusätzliche Referenzen: Castle.Core.dll Castle.MicroKernel.dll Castle.Windsor.dll MvcContrib.Castle.dll Castle MVCContrib
49
DI am Beispiel Castle Windsor protected virtual void InitializeWindsor() { if (m_Container == null) { m_Container = new WindsorContainer(); m_Container.AddComponentWithLifestyle( "repository", typeof(IRepository<>), typeof(Repository<>), LifestyleType.Transient); m_Container.RegisterControllers( Assembly.GetExecutingAssembly()); ControllerBuilder.Current.SetControllerFactory( typeof(WindsorControllerFactory)); }
50
Fragen? Email: stefan@lieser-online.destefan@lieser-online.de Blog: http://www.lieser-online.dehttp://www.lieser-online.de
51
Links Michael Feathers, Working Effectively With Legacy Code http://www.objectmentor.com/resources/articles/WorkingEffectivelyWithLegacyCode.pdf http://www.objectmentor.com/resources/articles/WorkingEffectivelyWithLegacyCode.pdf
52
Vielen Dank!
Ähnliche Präsentationen
© 2024 SlidePlayer.org Inc.
All rights reserved.