1. #1

    Registered
    08/11/03
    Location
    Antwerpen
    Posts
    1,726
    iTrader
    0
    Mentioned
    0 Post(s)
    Reputation
    2/2

    [PROG][.NET] Object vullen met Reflection

    Ik ben bezig met wat research in .NET.

    Momenteel probeer ik een zo goed mogelijke architecture te ontwerpen voor mijn applicaties. Alle details over die architectuur laat ik nu achterwege aangezien ze hier niet van belang zijn.

    Nu had ik een vraagje over het opvullen van mijn objecten. Het zit zo:
    - ik voor een stored procedure uit die een record teruggeeft
    - die waardes worden opgevangen in een datareader
    - ik geef het object dat moet worden opgevuld samen met de datareader door aan een procedure.
    - die procedure gaat aan de hand van reflection de properties van dat object koppelen aan de waardes die uit de database zijn gekomen.

    Code:
            Protected Sub FillDTO(ByRef dto As Object, ByVal dataReader As System.Data.Common.DbDataReader)
                If dto IsNot Nothing Then
                    Dim propertyInfo As System.Reflection.PropertyInfo = Nothing
                    Dim propertyValue As Object = Nothing
    
                    For Each propertyInfo In dto.GetType().GetProperties()
                        If propertyInfo.CanWrite = True Then
                            propertyValue = dataReader(propertyInfo.Name)
    
                            If propertyValue IsNot System.DBNull.Value Then
                                propertyInfo.SetValue(dto, propertyValue, Nothing)
                            End If
                        End If
                    Next
                End If
            End Sub
    Nu ben ik aan het twijfelen of het wel goed is om zo mijn objecten op te vullen. Reflection is traag en aangezien deze procedure zeer dikwijls wordt opgeroepen, kan dit in het nadeel van de performantie van mijn applicatie spelen.

    Is het dan niet beter om voor elk object een procedure te schrijven?
    no votes  

  2. #2
    AsinuS's Avatar
    Registered
    12/12/02
    Location
    Wichelen
    Posts
    133
    iTrader
    0
    Mentioned
    0 Post(s)
    Reputation
    0/0
    Ik gebruik altijd deze manier: Klasse die de connectie enzo afhandelt geeft een datareader terug. Het opvullen doe ik dan zoals hieronder staat.

    methode van de DataAccessor klasse:
    Code:
    Public Function GetAllUsers() As List(Of clsUser)
            Dim cmd As DbCommand = Database.CreateSPCommand("user_GetAll")
            Dim reader As DbDataReader = Database.ExecuteReader(cmd)
            Return ReadMultiple(reader)
        End Function
    of als je 1 object terug verwacht:
    Code:
    Public Function GetUserByUsername(ByVal naam As String) As clsUser
            Dim par As DbParameter = Database.CreateParameter("@naam", naam)
            Dim cmd As DbCommand = Database.CreateSPCommand("User_GetByName", par)
            Dim reader As DbDataReader = Database.ExecuteReader(cmd)        
            Return ReadSingle(reader)
        End Function
    voor het opvullen van de objecten gebruik ik dan deze methoden:
    Code:
    Private Function FillObjectData(ByVal reader As DbDataReader) As clsUser
            Dim oUser As clsUser = New clsUser
            oUser.ID = CType(reader("usr_id"), Integer)
            oUser.Naam = CType(reader("usr_NAAM"), String)
            oUser.Login = CType(reader("usr_LOGIN"), String)
            oUser.Paswoord = CType(reader("usr_PASWOORD"), String)
            oUser.Email = CType(reader("usr_EMAIL"), String)
            Return oUser
        End Function
    
        Private Function ReadSingle(ByVal reader As DbDataReader) As clsUser
            Try
                If reader.Read() Then
                    Return FillObjectData(reader)
                End If
                Return Nothing
            Finally
                reader.Close()
            End Try
        End Function
    
        Private Function ReadMultiple(ByVal reader As DbDataReader) As List(Of clsUser)
            Try
                Dim list As List(Of clsUser) = New List(Of clsUser)()
                While (reader.Read)
                    list.Add(FillObjectData(reader))
                End While
                Return list
            Finally
                reader.Close()
            End Try
        End Function
    no votes  

  3. #3

    Registered
    08/11/03
    Location
    Antwerpen
    Posts
    1,726
    iTrader
    0
    Mentioned
    0 Post(s)
    Reputation
    2/2
    Ik werk op net dezelfde wijze als u, AsinuS. Ook met ReadSingle en ReadMultiple enzo.

    Om een object op te vullen, schrijf ik normaal ook zo'n FillObjectData per DAL klasse. Maar om dat juist te vermijden, heb ik een 'generieke' procedure geschreven (FillDTO) en ze verhuisd naar men Database klasse, super klasse van alle DAL klassen (zoals bij jouw dus).

    Maar omdat die FillDTO heel veel gebruikt zal worden en aangezien ze met reflection werkt, is het misschien niet zo'n goed idee.
    no votes  

  4. #4
    Kn0t's Avatar
    Registered
    17/07/02
    Location
    #sskclan
    Posts
    336
    iTrader
    0
    Mentioned
    0 Post(s)
    Reputation
    0/0
    Ik ben geen .NET'er maar een J2EE'er.

    Maar ik zou zeggen: gebruik een Object<->DB mapping framework zoals hibernate? Je zet dan in een XML welke Object property mapt naar welke DB kolom. Hibernate doet de rest. Dit werkt ook er goed met relationships tussen verschillende objecten.

    Bestaat ook voor .NET (http://www.hibernate.org/343.html)
    no votes  

  5. #5

    Registered
    08/11/03
    Location
    Antwerpen
    Posts
    1,726
    iTrader
    0
    Mentioned
    0 Post(s)
    Reputation
    2/2
    Ik ken (n)hibernate en heb er al wel wat een beetje ervaring mee.

    Onder de motor gebruikt nhibernate trouwens ook reflection om objecten te vullen dacht ik .

    Bedankt voor je suggestie, maar ik ga toch bij mijn framework blijven .
    no votes  

  6. #6
    UniKorn's Avatar
    Registered
    20/09/02
    Location
    Leuven
    Posts
    460
    iTrader
    0
    Mentioned
    0 Post(s)
    Ik zou eerst eens kijken naar het csla framework (lothka)
    Uzghul, 70 Rogue; Tankghul, 70 Warrior; Uziuz, 70 Paladin; Skinny, 70 Priest; Darkrune, 70 Warlock; UniKorn, 60 Druid; Martinuz, 59 Hunter; Marceluz, 59 Mage; Flexy, 30 Rogue;
    no votes  

  7. #7
    Bavo aka Joske's Avatar
    Registered
    13/08/07
    Location
    Dendermonde
    Posts
    172
    iTrader
    0
    Mentioned
    0 Post(s)
    Reflectie is trouwens lang niet zo traag dan je zou denken, en zeker niet in deze context, aangezien SQL DB queries prolly een stuk langer duren dan het verlies wegens reflectie. De methode wordt wel vaker gebruikt om waarden over te zetten op dynamische wijze. En ja, ook Hibernate moet dit soms gebruiken (alhoewel het ook zuiver met geannoteerde getters en setters kan werken op POJOS).

    Ik begrijp uw methode, maar niet uw keuze om zelf een framework te maken. Dat is _altijd_ afgeraden tenzij het nergens anders bestaat. Je bent voortdurend bezig features in te bouwen die door andere makers al jarenlang gebouwd, verbeterd en debugged zijn.
    The next guy in line.
    no votes  

  8. #8
    Moto's Avatar
    Registered
    17/07/02
    Location
    Wilrijk
    Posts
    1,994
    iTrader
    2 (100%)
    Mentioned
    0 Post(s)
    Reputation
    9/16
    Nu ben ik aan het twijfelen of het wel goed is om zo mijn objecten op te vullen. Reflection is traag en aangezien deze procedure zeer dikwijls wordt opgeroepen, kan dit in het nadeel van de performantie van mijn applicatie spelen.

    Is het dan niet beter om voor elk object een procedure te schrijven?
    Bwa reflectie valt misschiens wel mee, maar zou toch het uitschrijven voor de meer belangrijke zaken/grote lijsten. zoveel tijd neemt het uiteindelijk allemaal niet in beslag.
    Ge kunt daarnaast deze functie voor de minder belangrijke/kritieke zaken gebruiken. En bv der ook speciek maken voor combo's (ID/DESC) die ge kunt hergebruiken.

    Maar het is alleszins al zeer goed dat ge bij uw eigen framework blijft

    Ik begrijp uw methode, maar niet uw keuze om zelf een framework te maken. Dat is _altijd_ afgeraden tenzij het nergens anders bestaat. Je bent voortdurend bezig features in te bouwen die door andere makers al jarenlang gebouwd, verbeterd en debugged zijn.
    Vraag mij af door wie dat afgeraden wordt, zal alleszins niet zijn door iemand met veel ervaring.
    Ge moet dan in de eerste plaats al weten wat dat framework kan en niet kan, en wat de requirements gaan zijn van uw project, + als dat framework technisch gezien dan ook geschikt gaat zijn.
    Dat is goed als ge in een team zit waar constant dingen gemaakt moeten worden met dezelfde requirements, maar hoeveel komt dat voor?

    Anyway zolang er van deze praat verkocht wordt zal ik tenminste niet zonder werk vallen, der is een vrij grote markt voor het redden van projecten die mislukken, meestal te wijten aan het ge/mis/bruik van frameworks
    Mensen zouden eerst eens beter nadenken over de negatieve kanten op lange termijn, dan snel snel iets in elkaar proberen te flansen
    no votes  

  9. #9

    Registered
    08/11/03
    Location
    Antwerpen
    Posts
    1,726
    iTrader
    0
    Mentioned
    0 Post(s)
    Reputation
    2/2
    UniKorn: dat CSLA-framework ziet er zeer deftig uit, ik ga dat binnekort zeker eens van dichter bij bekijken.

    Bavo aka Joske: de reden dat ik men eigen 'framework' schrijf is omdat ik dit vooral doe als leerproces. Ik wil heus niet opnieuw het warm water uitvinden hoor. Ik wil eerder weten wat er allemaal bij komt kijken bij een behoorlijk complexe lagenstructuur. En de beste manier om te weten te komen is door zelf een structuur te schrijven, vind ik.

    Moto: het opvullen dmv reflectie bevindt zich in mijn base DAL-klasse. Dus om complexere objecten op te vullen kan ik deze methode gewoon overriden . Ik ga mijn structuur nu verder uitwerken volgens deze gedachte.

    Bedankt iedereen voor jullie hulp.
    no votes  

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

Log in

Log in