Fetstil Fetstil Kursiv Understrykning linje färgläggning tabellverk Punktlista Nummerlista Vänster Centrerat högerställt Utfyllt Länk Bild htmlmode
  • Forum & Blog
    • Forum - översikt
      • .Net
        • asp.net generellt
        • c#
        • vb.net
        • f#
        • silverlight
        • microsoft surface
        • visual studio .net
      • databaser
        • sql-server
        • databaser
        • access
        • mysql
      • mjukvara klient
        • datorer och komponenter
        • nätverk, lan/wan
        • operativsystem
        • programvaror
        • säkerhet, inställningar
        • windows server
        • allmänt
        • crystal reports
        • exchange/outlook
        • microsoft office
      • mjukvara server
        • active directory
        • biztalk
        • exchange
        • linux
        • sharepoint
        • webbservers
        • sql server
      • appar (win/mobil)
      • programspråk
        • c++
        • delphi
        • java
        • quick basic
        • visual basic
      • scripting
        • asp 3.0
        • flash actionscript
        • html css
        • javascript
        • php
        • regular expresssion
        • xml
      • spel och grafik
        • DirectX
        • Spel och grafik
      • ledning
        • Arkitektur
        • Systemutveckling
        • krav och test
        • projektledning
        • ledningsfrågor
      • vb-sektioner
        • activeX
        • windows api
        • elektronik
        • internet
        • komponenter
        • nätverk
        • operativsystem
      • övriga forum
        • arbete karriär
        • erbjuda uppdrag och tjänster
        • juridiska frågor
        • köp och sälj
        • matematik och fysik
        • intern information
        • skrivklåda
        • webb-operatörer
    • Posta inlägg i forumet
    • Chatta med andra
  • Konto
    • Medlemssida
    • Byta lösenord
    • Bli bonsumedlem
    • iMail
  • Material
    • Tips & tricks
    • Artiklar
    • Programarkiv
  • JOBB
  • Student
    • Studentlicenser
  • KONTAKT
    • Om pellesoft
    • Grundare
    • Kontakta oss
    • Annonsering
    • Partners
    • Felanmälan
  • Logga in

Hem / Artiklar / Titel på artikeln

Underlätta explicit databindning

Postad 2008-10-29 av Jon Wiberg i sektionen ASP.NET, C#, Okategoriserat med 2 Kommentarer | Läst av: 3470, Betyg: 96%

Förord

Problembeskrivning Flera av de exempel som ligger ute på nätet visar hur man kan databinda mot en datakontroll i asp.net. Ofta visar de hur man binder ett dataset eller en datatable mot en datakontroll (och då ofta en gridview). I och med .net 2.0 kom en lite trevligare datakontroll: Object Datasource och en del utvecklare började mer och mer skapa klasser som representerade sin problemdomän. För problemdomänen skapas klasser som motsvarar delar i applikationen. En klass för t ex ett meddelande, en klass som representerar en användare mm. Man databinder sedan ofta listor med sina objektinstanser från klasserna mot olika datakontroller. Här uppstår då en lätt ”konflikt”. Man kanske använder den inbyggda eval (alt. Bind) metoden. Att eval:uera ett databundet objekt tar dock kraft/prestanda. Förutom att eval är prestandaineffektivt så anger man egenskapsnamnet med en stränglitteral Eval(”namnpåegenskap”).
Innehåll
  » Problembeskrivning
  » Lösningar
  » För tidigare version av .Net
  » Reflektioner
  » Ytterligare resurser


Problembeskrivning

fortsättning -

Mer info om varför eval är prestandaineffektivt finns under sektionen ”Minimize Calls to DataBinder.Eval" på

Problemen med hårdkodade strängar:
Problemen är att man kan stava fel, eller om egenskapsnamn ändras så kommer man inte upptäcka det.
Det går inte lika lätt att automatiskt förändra namnet på egenskapen till alla refererade ställen i koden när referensen är gjord som en sträng. Man kanske inte upptäcker felet förrän man kör applikationen och testar aktuell sida! (eller använder enhetstestning eller motsv.)
För mer info om att göra sig av med hårdkodade strängar se


Tidiga fel är bra fel. Om man kan visa på fel innan kompilation så är det i mitt tycke en bra sak.

Vad gör man då istället för att använda eval? Jo man cast:ar om objektet och säger eg. till applikationen att jag vet att det objekt du databinder mot är av typen T, t.ex. en instans från en egengjord klass med namnet Message.

Hur gör man det?
I t.ex. en datakontroll

<%# DirectCast(container.DataItem, Message).Titel %>

För mer olika exempel se:

det finns till och med en artikel här på Pellesoft om det sedan innan på:


Detta förfarande att cast:a kan dock bli tröttsamt att behöva skriva, och dessutom se (i mitt tycke) fult ut.



Lösningar

Jag har testat lite olika lösningar, bl a att skapa datakontroller vars Container.DataItem är starkt typat med att man kan skriva likn. nedan om dess Item är av Message typ.

<%# container.DataItem.Titel %>


Det blev lite finare, men ack att behöva skapa egna datakontroller för varje tänkbar klass!
Jag funderade vidare och tänkte göra en generell tex repeater av typ T, som returnerar ett item av Typ T. Detta skulle ev. fungera, men man behöver motsvarande för varje typ av datakontroll man vill använda sig av. Dessutom är inte ens container.DataItem.Titel särskilt ”sexigt”.

En lättare lösning blir då att börja se den bundna instansen som vad den eg. är och istället betrakta den som ett annat objekt. Med hjälp av Extension methods kommer här en förklaring till hur man skulle kunna förenkla vardagen med explicit databindning. För att få följande att fungera krävs det att man använder version 3.5 av .Net-ramverket.

Om man i VB skapar en Modul i sitt webbprojekt tex med namnet WebDataBindingHelper
Importerar en namnrymd: Imports System.Runtime.CompilerServices
Och skriver t ex:

_
Public Function AsMessage(ByVal container As System.Web.UI.IDataItemContainer) As Message
If container Is Nothing Then Return Nothing
Return DirectCast(container.DataItem, Message)
End Function


Så har vi i och med detta i ett slag refaktorerat bort behovet att göra en explicit typomvandlig från datakontrollen.

IDataItemContainer är ett trevligt interface som gör att det går oavsett om det är en Repeater eller en Gridview eller en Listview att behandla deras container likvärdigt.
Mer info om interfacet på:


Nu kan man istället skriva nedan i sin datakontroll:

<%# container.AsMessage.Titel %>


Semantiskt mycket finare och dessutom renare i och med mindre kod :D .

Varför går nu detta?
Jo extension methods utökar existerande klasser. Metoden AsMessage utökar/läggs på de objektinstanser av klasser som implementerat interfacet IDataItemContainer och gör att de nu har en pålagd funktion med namnet AsMessage.

Vad man behöver göra nu är alltså att göra extension methods för alla sina klasser vars objektinstanser man vill kunna databinda (som alternativ kan man ju alltid koppla på någon kodgenererare som gör en metod för varje åt en).

Vore det inte smidigare att kunna göra detta generellt?
En DirectCast kan ju cast:a till allt möjligt... Jo det går!

Låt oss nu göra just det genom att använda kraften av Generiska Typer. I modulen kan man nu skriva:


_
Public Function [As](Of T)(ByVal container As System.Web.UI.IDataItemContainer) As T
If container Is Nothing Then Return Nothing
Return DirectCast(container.DataItem, T)
End Function

Vad ovanstående kod gör är att möjliggöra en Container att typomvandla till vad som helst (förutsatt att man databundit med aktuell datatyp).

Har man databundit mot en lista av integer, strängar eller en komplex typ som t ex lista av instanser av klassen Message kan man nu göra det i sin kontroll enligt nedan:

<%# container.As(Of Message).Titel %>
<%# container.As(Of User).Username%> osv.



För tidigare version av .Net

Vad gör man om man har ett äldre projekt t ex i .net 2.0?
Ja då kan man inte använda extension methods, men man kan ju fortfarande underlätta databindning.
I sin modul kan man ju alltid skriva samma kod utan att dekorera med extension-attributet och då använda den koden enligt nedan:

<%# AsMessage(container).Titel %>



Reflektioner

Det kan argumenteras om det egentligen är containern och inte dess dataitem som borde ha metoden på sig. För dem som vill kan man då antingen använda hela Container.DataItem alternativt kanske försöka injicera så datakontrollerna exponerar DataItem direkt?

Vill man av någon anledning kunna typomvandla i vb.net m h a CType på databundet innehåll kan man ju göra det med t.ex. två olika metoder. En för typomvandling och en för DirectCast. Ex:
As: som returnerar CType(container.DataItem, T)
AsExactly: som returnerar DirectCast(container.DataItem, T)

Mer info om skillnaderna dem emellan på


Ytterligare resurser

Introduktion till Generics
*

.NET Introducing Generics in the CLR and Jason Clark (c#)
*

Använda generiska metoder
*

Extension Methods (Visual Basic)
*
*

Upp

2 Kommentarer


  1. Pelle Johansson
    29 okt 2008

    Verkligen väl skriven artikel och ett intressant ämne. Stort tack!


  2. Johan Normén
    29 nov 2008

    hej, Jag hade ju dock inte gjort så... men VB alltså hur fult är inte det språket... hehe kunde inte låta bli... men det är inte vackert. Har du tittat på ASP.Net MVC lite trevligare modell för hantera rednering av vyer. Ang din kod hade jag nog (om jag måste casta) kört på: <%# DirectCast(container.DataItem, Message).Titel %> I C# är ju koden snyggare så det är väl mkt där det faller med vb. Och då kan jag förstå lite din idé bakom detta. Om man bortser från lösningen så var det en intrerssant artikel som kan ge andra idéer för läsarna... Kul. Mvh Johan

Skriv en kommentar på artikeln

Ditt betyg på artikeln



Kommentar:





Nyligen

  • 09:09 Vill du köpa medicinska tester?
  • 12:47 Vem beviljar assistansen – kommune
  • 14:17 Någon med erfarenhet av hemstädnin
  • 14:14 Bör man använda sig av en båtförme
  • 14:12 Finns det någon intressant hundblo
  • 14:25 Tips på verktyg för att skapa QR-k
  • 14:23 Tips på verktyg för att skapa QR-k
  • 20:52 Fungerer innskuddsbonuser egentlig

Sidor

  • Hem
  • Bli bonusmedlem
  • Läs artiklar
  • Chatta med andra
  • Sök och erbjud jobb
  • Kontakta oss
  • Studentlicenser
  • Skriv en artikel

Statistik

Antal besökare:
Antal medlemmar:
Antal inlägg:
Online:
På chatten:
4 569 153
27 952
271 704
1 012
0

Kontakta oss

Frågor runt konsultation, rådgivning, uppdrag, rekrytering, annonsering och övriga ärenden. Ring: 0730-88 22 24 | pelle@pellesoft.se

© 1986-2013 PelleSoft AB. Last Build 4.1.7169.18070 (2019-08-18 10:02:21) 4.0.30319.42000
  • Om
  • Kontakta
  • Regler
  • Cookies