Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

ASP.NET MVC Stefan Lieser Web:

Ähnliche Präsentationen


Präsentation zum Thema: "ASP.NET MVC Stefan Lieser Web:"—  Präsentation transkript:

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!


Herunterladen ppt "ASP.NET MVC Stefan Lieser Web:"

Ähnliche Präsentationen


Google-Anzeigen