Gepost door: gert | februari 5, 2008

Berekenen van de reactie als objecten botsen

Om een realistische reactie op een botsing van objecten te programmeren, moet je de behoud van impuls en energie gebruiken… en liefst begrijpen ;)

Impuls (‘momentum’ in het Engels)

Stel je twee mannen voor, die even snel lopen. Eén van 60 kg en één van 120 kg. Als die twee op elkaar botsen, begrijp je dat ze een verschillende impact hebben. Met impuls kunnen we hun impact exact berekenen.

p = m * v -> impuls = massa * snelheid.

We passen dit toe op onze mannen (ik hou me hier niet bezig met de correcte eenheden):

p1 = 60 kg * 8 km/u = 480
p2 = 120 kg * 8 km/u = 960

Conclusie: de impuls van de tweede man is dubbel zo hoog als van de eerste man, een beproefde sumo-worstel-strategie.

Behoud van impuls

Dit betekent dat de totale impuls voor en na de botsing, gelijk zijn.

Energie

Energie wordt opgedeeld in statische en kinetische energie. Kinetische energie is de energie van een object in beweging en relevant voor ons.

E = 1/2 * m * v² -> Energie is massa, vermenigvuldigd met snelheid in het kwadraat, gedeeld door 2.

Behoud van energie

Ook voor energie geldt, dat de totale eneregie voor de botsing, gelijk is aan de totale energie na de botsing.

We rekenen uit

Voor de botsing

p1init = m1 * v1init
p2init = m2 * v2init
pInit = p1init + p2init -> de totale impuls

e1init = 1/2 * m1 * v1init²
e2init = 1/2 * m2 * v2init²
eInit = e1init + e2init -> de totale energie

Na de botsing

Tijdens de botsing werken er krachten in op de twee mannen. Als we deze krachten kennen, weten ook wat hun reactie zal zijn. Voor de berekening hebben we het behoud van impuls en energie nodig.

p1F = m1 * v1F
p2F = m2 * v2F
pF = p1F + p2F

e1F = 1/2 * m1 * v1F²
e2F = 1/2 * m2 * v2F²
eF = e1F + e2F

We passen het behoud van impuls toe:

pInit = pF = p (zie later)
m1 * v1init + m2 * v2init = m1 * v1F + m2 * v2F
m1(v1init – v1f) = m2(v2F – v2init)

We passen het behoud van energie toe:

eInit = eF
1/2 * m1 * v1init² + 1/2 * m2 * v2init² = 1/2 * m1 * v1F² + 1/2 * m2 * v2F²
m1(v1init² – v1F²) = m2(v2F² – v2init²)
m1(v1init + v1F)(v1init – v1F) = m2(v2F + v2init)(v2F – v2init) -> Factoren, weet je nog?’

We delen e door p om zo de snelheid v te kunnen bereken. Hè hè, reeds heel wat ballast kwijt.

v1init + v1F = v2F + v2init
v1init – v2init = v2F – v1F

We stellen het volgende:

p = pInit = pF -> behoud van impuls
v = v1init – v2init -> deze snelheden zijn gekend

Dan volgt :

p = m1v1F + m2v2F -> zie hoger

v = v2F – v1F
v1F = v2F – v

we combineren:

p = m1(v2F – v) + m2v2F
p = v2F(m1 + m2) – vm1
v2F = p + vm1 / m1 + m2

Het eindresultaat

We wilden de nieuwe snelheden voor beide mannen bereken, et voila!

v2F = p + vm1 / m1 + m2
v1F = (v2init + v2F) / v1init –> zie hoger

Gepost door: gert | januari 28, 2008

De logic operator || aka OR

Een klein OR-truukje

Algemeen

De logische operator|| in ActionScript betekent OR. Wat dat betekent is vrij duidelijk: in een test evalueert de test naar true als één van de testen als true wordt geëvalueerd.

Een voorbeeldje uit de help file:

var x:Number = 10;
var y:Number = 250;
var start:Boolean = false;
if ((x > 25) || (y > 200) || (start)) {
trace(“the logical OR test passed”);
}

Het truukje

Minder bekend is dat je onderstaande methode, korter kan schrijven let de OR operator:

Zonder ||

// CONSTRUCTOR
public function Cube(mc:MovieClip) {
if (mc == undefined) mc = _level0
trace( “vMc : ” + vMc );
}

Ik maak een cubus op een bepaalde MovieClip. Als de mc niet gespecifieerd wordt in het argument van de constructor, wordt _level0 als default mc genomen. Deze manier van werken gebruik ik regelmatig.

Met ||

Dit script kan je ook, korter, als volgt schrijven:

// CONSTRUCTOR
public function Cube(mc:MovieClip) {
vMc = mc || _level0
trace( “vMc : ” + vMc );
}

Verklaring

vMc = mc || _level0

Indien mc undefined is, wordt _level0 gebruikt. Testen op undefined geeft immers false terug:

if (undefined)
trace(“test gelukt”);
else
trace(“test mislukt”);

Voila, een kleine, simpele tip.

Gepost door: gert | januari 21, 2008

Tabs in textfield

De mogelijkheden voor tekst, zijn in Flash soms bedroevend laag. Ik was dan ook aangenaam verrast dat het mogelijk is om tabs te gebruiken in een textfield. Daarvoor moet je escape characters gebruiken in een html-textfield, met een textformat tag, met het tabStops attribuut.

Een voorbeeld

  1. Teken een cirkel op de stage, maak er een MovieClip van met instance naam “cicrle_mc”
  2. Plaats onderstaand script in de Actions (uiteraad op een eigen layer)

this.createTextField(“mouse_txt”, this.getNextHighestDepth(), 0, 0, 300, 300);
mouse_txt.html = true;
mouse_txt.multiline = true;
var head:String = ” \t<b>_xmouse\t</b><b>_ymouse</b>”;
circle_mc.onMouseMove = function() {
mouse_txt.htmlText = “<textformat tabStops=’[100,200]‘>”;
mouse_txt.htmlText += head;
mouse_txt.htmlText += “<b>_level0</b>\t”+_xmouse+”\t”+_ymouse;
mouse_txt.htmlText += “<b>my_mc</b>\t”+this._xmouse+”\t”+this._ymouse;
mouse_txt.htmlText += “</textformat>”;
};

3. exporteer.

Je krijgt de positie van de muis, weergegeven in een tabel.

Analyse

  1. Een textfield wordt toegevoegd met html formatting.
  2. Een string wordt aangemaakt met escape characters, voor het hoofd van de tabel
  3. Een callback function wordt toegevoegd, als eventhandler van het event ‘MouseMove’
  4. Aan het textfield wordt een Texformat tag toegvoegd met attribuut tabStops
  5. Tabs worden gebruikt in de htmlText
Gepost door: gert | januari 16, 2008

Little Bubble

In een vorig artikel legde ik Bubble Sort uit. Dit algoritme sorteert een volledige lijst.

Maar wat moet je doen, als je slechts één element wenst toe te voegen, aan een reeds gesorteerde lijst? Een volledige Bubble Sort is dan zwaar overkill.

Little Bubble

Als er slechts één element moet ‘gebubbled’ worden, is een geneste iteratie niet meer nodig.

class Sort{

public static function addBubble(a:Array, obj:Object):Array {

// maak een copie om de originele array ongemoeid te laten
var vA:Array = a.splice(0) ;
vA.push(obj) ;
var len:Number = vA.length – 1
for (var i:Number = len; i > 0; i–) {
if (vA[i] < vA[i - 1]) {
// swap the items
var k:Number = vA[i] ;
vA[i] = vA[i - 1] ;
vA[i - 1] = k ;
}else {
break ;
}
}
return vA ;
}
}

De parameter a is een reeds gesorteerde array. Dit is niet verplicht, maar de bubble (in dit geval het getal n) stopt met opschuiven, eens hij een kleiner getal in de rij tegenkomt.

Implementeren in de Flash IDE:

var l:Array = new Array(7, 3, 8, 9, 4, 5, 6, 1, 2, 10);
l = Sort.bubbleSort(l);
trace(l);
//
l = Sort.addBubble(l, 3.5);
trace(l);

Het getal 3.5 komt mooi tussen 3 en 4 te staan.

Omdat de tweede parameter van addBubble een object is, kan je deze soort even goed gebruiken voor bvb. een string, om alfabetisch mee te rangschikken. Maar dat is reeds voorzien in Array.sort()

Gepost door: gert | januari 16, 2008

Bubble sort

Sorteren met ActionScript

Als je met ActionScript een Array sorteert, krijg je een onverwacht resultaat. We sorteren een getallenrij van 1 tot 10:

var l:Array = new Array(7,9,4,5,2,10,6,8,3,1)
trace(l.sort())

Het resultaat:

1,10,2,3,4,5,6,7,8,9

De sort() methode van Array, sorteert alfabetisch en niet numeriek.

Bubble Sort

Om arrays te sorteren, bestaan er verschillende algoritmen. Een eenvoudige en populaire is de Bubble Sort. Zo genoemd, omdat kleinere waarden achteraan de array, langzaam naar boven komen drijven, bij elke iteratie. Grotere waarden daarentegen, worden snel achteraan geplaatst. In dit verband spreek men, zeer plastisch, over schildpadden en konijnen.

Bubble Sort implementeren

In een Sort klasse pas ik het Bubble Sort algoritme toe.

class Sort {
public static function bubbleSort(a:Array) {
// Make a copy of the orginal array to keep it unchanged
var vA:Array = a.splice(0) ;
var len:Number = vA.length – 1 ;
for (var i:Number = 0; i < len; i++) {
for (var j:Number = len; j > i ; j–) {
if (vA[j] < vA[j - 1]) {
// swap the items
var k:Number = vA[j] ;
vA[j] = vA[j - 1] ;
vA[j - 1] = k ;
}
}
}
return vA
}
}

We passen het toe in de Flash IDE:

var l:Array = new Array(7, 3, 8, 9, 4, 5, 6, 1, 2, 10);
l = Sort.bubbleSort(l);
trace(l);

Het resultaat:

1,2,3,4,5,6,7,8,9,10

Besluit

Bubble sort is een eenvoudig algoritme, maar niet bruikbaar voor grotere lijsten. Bovendien is er een groot verschil in performantie, naargelang er veel kleinere waarden zich vanachter in de lijst bevinden, of eerder vooraan. Andere, meer complexe sorteertalgortimen pakken dit probleem aan.

De test op ‘kleiner dan’ is afhankelijk van het datatype van het object. In dit geval waren het integers, maar je kan even goed voor objecten kiezen.

Gepost door: gert | januari 12, 2008

Hash code

Wat is de Hash code?

Als een object geïnstantieerd wordt, krijgt het een nummer mee: de Hash code. De methode Object.GetHashCode() geeft dit nummer terug. Deze code is een Int32 en volgt de volgende regels:

  • Als twee objecten gelijk zijn, moeten de methodes GetHashCode() dezelfde code teruggeven.
  • Als twee objecten niet gelijk zijn, kunnen ze toch dezelfde Hash code hebben.
  • Zolang een object niet wijzigt, op dusdanige manier dat de Equals methode een andere waarde teruggeeft, geeft het dezelfde Hash code terug.
  • Als de applicatie wordt herstart, kunnen de Hash codes veranderen.

De meeste van deze regels zijn behoorlijk logisch. Opvallend is dat de Hash code van een object niet gegarandeerd uniek is. Ergens begrijpelijk, aangezien het slechts een Int32 is (4 bytes), terwijl een guid (wel een unieke code) 16 bytes groot is (128 bits).

Equals

Als je de methode Object.GetHashCode() overschrijft, moet je ook de methode Object.Equals() overschrijven, om zeker te zijn dat twee identieke objecten ook dezelfde Hash code teruggeven.

Hash tabel

Dit zijn tabellen met name-value pairs als kolommen. In dit geval de Hash code en het object.

Gepost door: gert | januari 8, 2008

Gebruik van delete en de garbage collector

Het delete keyword

Wat doet het keyword ‘delete‘ nu eigenlijk?

Eerst enkele belangrijke begrippen:

Er zijn 2 grote groepen van variabelen:

  • value types
  • reference types

Value types

Bevatten effectief een waarde en worden bewaard op de stack. Value types binnen ActionScript zijn primitieve variabelen: boolean, Number, String.

var getal:Number = 5;
var naam:string =”gert”;

Reference types

Deze variabelen worden bewaard op de heap. Zoals de naam suggereert, verwijzen deze variabelen. Via een pointer worden de effectieve waarden gevonden, op de stack. Voorbeelden zijn: Array, Object.

var namen:Array = new Array(“Gert”,”Bert”,”Wim”) ;

Om aan te tonen dat het hier inderdaad over reference types gaat, het volgende voorbeeld:

var getallen1:Array = new Array(1,2,3,4,5);
var getallen2:Array = getallen1;
getallen2.shift();
trace(getallen1[0]);
/* In getallen1 blijkt het eerste cijfer op miraculeuze wijze verdwenen te zijn. De reden is natuurlijk dat getallen1 en getallen2 een pointer hebben naar dezelfde array. */

Een interessante discussie op flashfocus.nl hierover, lees vooral wat Dauntless erover schrijft.

Delete

Het keyword delete zal nu de pointer verwijderen. De oospronkelijke variabelen blijven wel bestaan, maar worden vrijgegeven voor de garbage collector van de Flash Player. Een zeer interessant artikel vind je hier. Ik geef een samenvatting voor AS2.

Garbage collector

Als sinds AS1 bestaat er een garbage collector in de Flash Player. Een garbage collector zal een object verwijderen waar een applicatie niet meer naar verwijst.

var o:Object = new Object();
o.foo = “bar”;
var oRef:Object = o;
delete o;
trace(b.foo);

De verwijzing naar de property van o blijkt nog steeds te bestaan, ook al werd het object verwijderd. Indien oRef ook ge-delete-d zou worden, wordt de property foo (uiteindelijk ook een object) vrijgegeven voor de garbage collector.

Reference counting

De garbage collector werkt in bovenstaand voorbeeld via reference counting. Als een object naar een ander object verwijst, wordt zijn referentie-aantal verhoogd. Als een referentie verwijderd wordt, wordt dit aantal vermindert. Als een object zijn referentie-aantal gelijk is met nul, wordt het object vrijgegeven om door de garbage collector te worden opgeruimd.

Het is een eenvoudig systeem, niet te belastend voor de CPU en werkt goed in de meeste situaties.

Mark and Sweep

Maar in complexe situaties, als objecten naar elkaar verwijzen, werkt reference counting niet meer. Ook al gebruikt een applicatie bepaalde objecten niet meer, de referenties blijven toch bestaan.

Een voorbeeld

var a:Object = new Object();
var b:Object = new Object();
b.foo = a;
a.foo = b;
delete a;
delete b;

Hoewel de applicatie op geen enkele manier deze objecten kan aanspreken (ze werden deleted), staat hun referentie-aantal wel op één. Het gevolg is dat de garbage collector deze objecten niet kan verwijderen d.m.v. reference counting. Herinner dat delete geen objecten verwijdert, maar enkel hun pointer.

Dit probleem duikt bvb. op bij het xml-object. Elke xmlNode heeft een referentie naar zijn parent en naar zijn childNodes en kan dus nooit verwijderd worden.

Om dit probleem op te lossen introduceerde Flash Player 8 ‘mark and sweep’.

Hoe werkt het?
  1. De Flash Player begint bij het root-object van de applicatie en zoekt al de referenties die dit object heeft. Elk van de gevonden objecten wordt gemarkeerd.
  2. Daarna loopt de Flash Player door al gemarkeerde objecten op een recursieve manier, totdat elk object van de applicatie – met een actieve referentie – gemarkeerd is.
  3. De objecten die nog in het geheugen bestaan, maar niet gemarkeerd werden, hebben geen actieve referentie en worden vrijgegeven voor de garbage collector.

Dit systeem is zeer nauwkeurig, maar zwaarder voor de CPU. Om dit probleem gedeeltelijk op te lossen gebruikt de Flash Player 8 incremental garbage collection. Dit betekent dat het markeren van de objecten en het effectief verwijderen van objecten, niet op hetzelfde moment gebeurt. Het verwijderen gebeurt als er voldoende geheugen vrij komt. Dit resulteert in gemiddeld 50% minder verbruik van geheugen, vergeleken met Flash Player 7 (niet altijd, de details vind je onder onderstaande link).

Interessante lectuur over de verbeteringen van Flash Player 8.

Kan een object zichzelf deleten?

Als ik delete gebruik via een publieke methode destroy (bvb.). Zal de garbage collector dit object dan verwijderen? We testen:

class TestDelete {
private var vText:String = “” ;
public function destroy():Void {
delete this ;
}
public function get text():String {
return vText ;
}
public function set text(value:String) {
vText = value ;
}
}

Een eenvoudige klasse waaraan je een tekst meegeeft en die de methode destroy implementeert, waarin het object zichzelf vernietigt. We implementeren deze klasse in de Flash IDE:

var t = new TestDelete();
t.text = “I’me alive”;
t.destroy();
setInterval(this, “log”, 1000);
function log():Void {
trace(t.text);
}

Resultaat: Het object blijft leven. M.a.w. een object kan zichzelf niet vernietigen!

Om een object te verwijderen, moet je het benaderen van buitenaf:

var t = new TestDelete();
t.text = “I’me alive”;
delete t ;
setInterval(this, “log”, 1000);
function log():Void {
trace(t.text);
}

Een interessante blog, hier over memory leaks en garbage collection.

Gepost door: gert | december 14, 2007

Model View Presenter

Korte beschrijving

Het is niet de bedoeling om de logica van het domein in de grafisch componenten te plaatsen. Dit is moeilijk te onderhouden, code is verspreid en wordt gecopieerd en is enkel te testen door de applicatie te runnen

De elementen van MVP

.MVP relaties

Het Model

Het model object bevindt zich op domein niveau. Soms (niet helemaal correct) omschreven als business model. Het model bevat de data van de applicatie en voorziet methodes om de data beschikbaar te maken. bvb. een Personal Account. Het model bevat ook de businesslogica.

Het model heeft geen weet van de presenter of de view.

De View laag

De UI laag bevat de forms en de controls. Ze is verantwoordelijk voor het tonen van de data aan de gebruiker. Voor Web Forms zijn dat ASP.NET web forms, user controls, server controls. Voor Windows Form zijn dat Window Forms, user controls, libraries.

Typisch aan een passieve view is dat de View geen weet heeft van het model.

Om de applicatie gemakkelijk te testen, maken we deze laag zo klein en dom mogelijk, door alle logica van de GUI in de presentatielaag te plaatsen. Het concept ‘humble object‘ doet zijn intrede: elk object dat moeilijk te testen is, mag maar zeer beperkte functionaliteit hebben. Een tweede voordeel is dat je een andere ‘skin‘ kan gebruiken voor de applicatie, zonder de logica aan te moeten passen.

De Presentatielaag

De Presentatielaag implementeert hoe de UI-elementen zich gedragen: validatie, input voor de UI,… Ze kent de View laag, maar voor flexibiliteit is programmeren we naar een IView interface. De handelingen van de gebruiker worden in eerste instantie opgevangen door de View en onmiddellijk doorgegeven aan de Presenter voor verwerking.

De presentatie laag manipuleert de data van het model op basis van de input van de gebruiker.

Je kan de Presenter zien als de ‘hub’ van de structuur en de View als de ‘skin’.

UI en Presenter bevinden zich in verschillende packages.

Een datalaag

Indien er een datalaag gebruikt wordt in de applicatie, zal de Presenter het persisteren in gang zetten, via een persisteerder object. Dit – uiteraard – in opdracht van de View. De Presenter plaatst de gegevens van de View in het Model en met deze gegevens wordt de persisteerder gevoed.

Op het eerste gezicht leek dit een omweg. Waarom voegt de Presenter eerst de gegevens in het model en gebruikt dan dit model om deze gegevens door te geven aan de Persister? De reden is dat het model de Persistente klassen bevat. De Presenter geeft de gegegevens van het model door aan de persister, via de persitente objecten.

Voor meer uitleg over het gebruik van een datalaag, verwijs ik naar de Hybernate-sectie van deze blog.

Soorten MVP’ers

Een nadeel van het splitsen in verschillende lagen is, dat er meer code moet geschreven worden. Afhankelijk van het desing pattern dat je kiest, resulteert dit in meer of minder code.

Er zijn 3 manieren:

  1. de Seperated Presentation and Passive View : de presenenter is een soort controller die de user events afhandeld en ook de view updatet.
  2. de Supervising Controller plaatst eenvoudige logica in de view
  3. Presentation Model behandelt alle data en behaviors en synchroniseert met de view.

In alle gevallen wordt de afhandeling van de events onmiddellijk doorgegeven naar de controller. De keuze tussen deze 3 patterns is voor een groot deel persoonlijke smaak. Het ene pattern geeft meer logica aan de View dan de andere. Wij kiezen hier voor Passive View. Alle logica wordt afgehandeld door de Presenter. Je moet meer code schrijven, maar is eenvoudig te implementeren.

Passive View

De View wordt volledig gecontroleerd door zijn controller, de Presenter. View en Model kennen elkaar niet. Omdat de View zo weinig doet, loop je ook geen groot risico als je hem niet test.

Supervising Controller

Bekijk deze geweldige videoreeks

Conclusie

MVP is een krachtig design pattern dat een goede oplossing biedt, voor het organiseren van je code. In vergelijking met MVC zijn de verantwoordelijkheden duidelijker verdeelt. Ik heb nu een paar werken met de passive view variant gewerkt en ik vind hem een beetje overkill. Omdat in de passive view, de view niets weet van de model, moet hij via properties alles doorgeven aan de Presenter. Persoonlijk vind ik het eenvoudiger dat de View bvb. een klant uit het Model doorgeeft naar de Presenter. Logica die te maken hebben met de GUI, validatie, enz. laat ik over aan de Presenter. Het idee van een ‘domme’ View volg ik wel.

Gepost door: gert | december 12, 2007

SCRUM basis

Scrum is een vorm van Agile development, toegespitst op kleinere teams.

Typische rollen binnen SCRUM zijn de varkens en de kippen. Varkens zijn volledig toegewijd tot het project, terwijl de kippen eerder een ondersteunende rol hebben, dixit de volgende grap:

A pig and a chicken are walking down a road. The Chicken looks at the pig and says “Hey, why don’t we open a restaurant?” The pig looks back at the chicken and says “Good idea, what do you want to call it?” The chicken thinks about it and says “Why don’t we call it ‘Ham and Eggs’?” “I don’t think so” says the pig, “I’d be committed but you’d only be involved”

Gepost door: gert | december 12, 2007

NHibernate

NHibernate is een ORM voor .NET. ORM staat hier voor Object Relation Mapper. NHibernate zorgt voor de vertaling van een OO model naar het relationeel model van een database. Het is de data-access laag van de applicatie.

SQL kennen is niet meer nodig

NHibernate creëert de sql statements zelf.

  • Standaard CRUD-operaties worden uitgevoerd door een eenvoudige mapping
  • voor complexe queries bestaat de Criteria API

Lazy loading

Standaard heeft NHibernate op elke collectie lazy loading geïmplementeerd.

Vb.: Stel je een bibliotheek voor, waarbij lezers boeken kunnen ontlenen. Als je een lijst wil van lezers moeten de ontleende boeken niet ingelezen worden.

Complexe queries

Voor joins en condities, kan je HQL gebruiken. Deze taal lijkt op sql, maar gebruik je op een OO manier.

Persistente klasse

De klassen die NHibernate moet persisteren, zijn POCO’s (Plain Old CLR Objects) . De persistente klassen volgen de volgende regels:

  • Ze gebruiken properties. Al de datatypes van .NET worden ondersteund.
  • Ze hebben geen constructor. Default zal een parameterloze constructor worden aangemaakt.
  • Optioneel maar aan te raden: een Id die de private key bevat.
    bvb. ISession.SaveOrUpdate() is alleen beschikbaar voor klassen die een Id gebruiken
  • Optioneel: virtuele methodes of methodes gedefinieerd in een interface
  • Optioneel: overschrijf de Equals() en GetHashCode() methode. Als je 2 identieke objecten laadt in verschillende ISessions, zijn ze niet meer gelijk!

Persisteerder klasse

Deze klasse gaat de persistente klasse persisteren in de database.

Configuratie

We moeten een ISession opstarten via de ISessionFactory. Een ISessionFactory is thread-safe. Ze is verantwoordelijk voor één database en wordt één maal aangemaakt. Ze moet dan ook bereikbaar zijn, overal binnen de applicatie en daarom gebruiken we het Singleton pattern.

Eens de ISessionFactory is aangemaakt, kan je ze niet meer wijzigen. Daarom moeten we de configuratie eerst aanmaken. Via configuratie.BuidSessionFactory() verkrijgen we de ISessionFactory met (uiteraard) de ingestelde configuratie.

Protected Overridable Sub config()
Const resource As String = “.NHibernate.cfg.xml”
‘ haal assembly op waarin de mapping files zich bevinden
‘ hier bevindien die zich in de assembly van de applicatie zelf

Dim assembly As System.Reflection.Assembly = Me.GetType.Assembly
Dim resourceName As String = assembly.GetName.Name + resource
‘ configureer NHibernate
Dim cfg As New NHibernate.Cfg.Configuration()
‘resource is het pad van de NHibernate config file
cfg.Configure(resource)
cfg.AddAssembly(assembly)
Dim factory As NHibernate.ISessionFactory = cfg.BuildSessionFactory()
mSession = factory.OpenSession()
mSession.Disconnect()
End Sub

Xml mapping bestanden groeperen en importeren

Het is niet aan te raden om de mapping van al de klassen in één groot mapping bestand te doen. De beste manier om dan de verschillende xml bestanden te importeren, is door ze in een assembly te verzamelen. NHibernate gaat op zoek in de assembly naar bestanden met de extensie .hbm.xml

Als je met Visual Studio werkt, vergeet dan niet aan te geven dat deze xml-bestanden een embedded source zijn, anders worden ze niet in de assembly geplaatst.

Configureren van de applicatie

Dit kan via code, maar hier wordt gekozen om de configuratie via een xml-bestand te doen. Plaats deze file in de map van de applicatie.

Een component

Een component voor NHIbernate is het equivalent van composition in een OO model. De properties van de component worden toegevoegd als velden van de tabel. Het is een manier om meerdere klassen te mappen naar één tabel.

Relaties tussen klassen

NHibernate ondersteund volgende relaties:

  • many-to-one: todo
  • one-to-many: bvb. een set of een bag. Het object bevat een collectie van andere objecten.
  • many-to-many: 2 klassen hebben elk een collectie die objecten van de andere klassen bevat

MS-SQL database

Tabellen aanmaken

Ik had even gehoopt dat NHibernate de tabellen van een lege database zelf zou aanmaken, no such luck;). Dus zelf tabellen aanmaken, anders krijg je de foutmelding van NHibernate dat bvb. het object ‘tblKlant’ niet bestaat.

Primairy key

Omdat een klantnnummer uniek moet zijn, gebruik ik het de PK van tblKLant. Maar ik kreeg de foutmelding van de sql-server ‘could not insert NULL in ID’. Ik was immers vergeten om de identity van de PK in te stellen in de database. Omdat ik de PK ook als klantnummer gebruik, stel ik de identity seed in op 1000 (dat oogt beter op een factuur;))

« Nieuwere berichten

Categorieën

Follow

Get every new post delivered to your Inbox.