-
01-09-2007, 13:39 #1Member
- 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.
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.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
Is het dan niet beter om voor elk object een procedure te schrijven?no votes
-
-
01-09-2007, 16:20 #2
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:
of als je 1 object terug verwacht: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
voor het opvullen van de objecten gebruik ik dan deze methoden: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
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 Functionno votes
-
02-09-2007, 13:51 #3Member
- 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
-
02-09-2007, 16:15 #4
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
-
03-09-2007, 20:14 #5Member
- 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
-
10-09-2007, 18:26 #6
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
-
11-09-2007, 10:25 #7
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
-
13-09-2007, 18:58 #8Member
- Registered
- 17/07/02
- Location
- Wilrijk
- Posts
- 1,994
- iTrader
- 2 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 9/16
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.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?
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
Vraag mij af door wie dat afgeraden wordt, zal alleszins niet zijn door iemand met veel ervaring.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.
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 flansenno votes
-
13-09-2007, 19:48 #9Member
- 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
