Polymorphism in ASP.net MVC

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • DEiE
  • Registratie: November 2006
  • Laatst online: 29-09 16:32
Een goede maandagmorgen,

Ik zit met een designprobleem wat ik denk ik het beste kan illustreren aan de hand van een voorbeeld.
Stel, we stellen een website op waarop auto's verkocht kunnen worden. Er worden verschillende soorten auto's verkocht, van normale personenauto's tot vrachtwagens en campers. Bij een personenauto is het aantal zitplaatsen van belang, bij vrachtauto's de laadruimte, etc.

Dit kan worden herleid naar de volgende klassedefinities van viewmodels (nederlandse namen zijn enkel voor de duidelijkheid):

C#:
1
2
3
public abstract class Auto { }
public class Personenauto : Auto { }
public class Vrachtauto : Auto { }


Ik wil een lijst tonen met alle beschikbare auto's, waarin dus verschillende subtypes aanwezig zijn. Mijn eerste idee is om dit met polymorphism op te lossen. De viewmodel voor Auto krijgt een abstracte methode om te renderen, welke door de subtypes geimplementeerd wordt. In de view kan deze methode vervolgens worden aangeroepen.

Viewmodels:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public abstract class Auto {
   public abstract void Render(HtmlHelper htmlHelper);
}

public class Personenauto : Auto {
   public override void Render(HtmlHelper htmlHelper)
   {
      // Logica om Personenauto te renderen
   }
}
public class Vrachtauto : Auto {
   public override void Render(HtmlHelper htmlHelper)
   {
      // Logica om Vrachtauto te renderen
   }
}


View:
code:
1
2
3
4
5
@using IEnumerable<Auto>
@foreach(Auto auto in Model)
{
   auto.Render(Html)
}


Op deze manier kan de pagina worden gerendered, zonder dat ik in de view dingen hoef te doen als
code:
1
2
3
4
5
6
7
8
9
10
11
12
@using IEnumerable<Auto>
@foreach(Auto auto in Model)
{
   if(auto is Personenauto)
   {
      Html.Partial("Personenauto", auto)
   }
   elseif(auto is Vrachtauto)
   {
      Html.Partial("Vrachtauto", auto)
   }
}

en daardoor elke keer de view moet wijzigen als er een nieuw type auto bijkomt. Echter breekt dit volgens mij het idee van het MVC-pattern, omdat hierbij het (view)model kennis heeft over de manier waarop hij gerendered moet worden, en hierdoor de view niet kan worden gewisseld.

Graag zou ik jullie input willen, hoe dit op een nette manier op te lossen valt.

Bij voorbaat dank voor jullie inbreng,
DEiE

Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Waarom maak je geen uitbereiding (extensie) voor de HtmlHelper welke de auto als parameter meekrijgt.

C#:
1
2
3
4
5
6
7
public static class VoertuigHtmlRenderHelper
{
  public static string RenderAuto(this HtmlHelper htmlHelper, Auto auto)
  {
     ...
  }
}


Op die manier kun je het renderen van het 'voertuig' buiten je viewmodel houden, en toch flexibel houden. Een ander voordeel is dat als je later overschakeld naar een andere view engine (zoals de XslViewEngine) de HtmlHelper ook niet in de weg zit.

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • DEiE
  • Registratie: November 2006
  • Laatst online: 29-09 16:32
Hier heb ik wat aan, bedankt!

Zoals je aangeeft, heb ik nog altijd de if-else structuur, alleen wordt deze verplaatst naar een centrale plaats. Hierdoor kan ik mijn views wat generieker opstellen, en binnen de HtmlHelper de partial renderen.

Acties:
  • 0 Henk 'm!

  • D-Raven
  • Registratie: November 2001
  • Laatst online: 10:35
Lees je eens in in de Html.Display en Html.DisplayFor extensies.

Volgens mij doet die precies wat je wilt.