Wanneer je manager een nieuwe techniek ten strengste verbied met als argument
'we snappen je code normaal al niet, dit maakt het alleen maar erger'
weet je dat je goud in handen hebt. Voor een eigen projectje om vals te spelen met Football Manager
(waar ik later absoluut nog eens terug kom) had ik globaal de volgende
situatie:
Leuk, neat, en vrij goed te lezen; probleem alleen dat ik een paar honderd
properties heb, met een stuk of zeven verschillende types. Te veel werk.
En aangezien je in eigen projecten toch helemaal los mocht gaan, leek een
oplossing op basis van AOP me veel leuker. Nieuwe situatie:
Bovenstaande is best eenvoudig werkend te krijgen met PostSharp, een framework voor Aspect Oriented Programming in .NET. Een eenvoudige implementatie
van bovenstaande is iets als:
Je kunt nu alle logica die toch steeds hetzelfde is, eenvoudig webabstraheren
in een aparte file. Maar... té traag. In mijn geval werd het bepalen
van de rating voor spelers ruim tien keer zo traag; door alle overhead.
Oplossing? Zelf MSIL injecten!
MSIL? MSIL, de immediate language van Microsoft (vergelijkbaar met Java's
bytecode) is een stack-based taal die uiteindelijk wordt uitgepoept als
de compiler je C# code compileert. Shameless kopie van Wikipedia:
MSIL injection? Eén van de leukste functies van PostSharp is, is dat het op basis
van de attributes die je set, en de implementatie die je daarna schrijft
direct ná compilatie extra code aan je assembly toevoegd. De AOP code
zit dus in je DLL geweven. Het mooie hieraan is, is dat je ook zelf extra
code kan toevoegen via PostSharp. Hiermee ben je dus niet gebonden aan
de (trage) versie die PostSharp je aanbiedt.
Uh dus? Als basis heb ik de volgende helper-functie gemaakt: PropertyInvoker.cs. Deze moet vanuit elke property worden
aangeroepen:
Ergo: we moeten de implementatie van onze property on the fly gaan veranderen.
Yay!
Get it started We beginnen met het maken van een Task, waarin we aangeven op welk 'attribute'
we werken: in dit geval 'FMEntityAttribute'. Hierna kunnen we
een Advice schrijven, waarin we de daadwerkelijke implementatie
doen.
Weave De 'weave' method is het hart van het 'Advice'. Deze
wordt aangeroepen voor elke property waarop we ons attribute hebben gezet.
WeaveGetter In de 'WeaveGetter' kunnen we nu de MSIL gaan schrijven om de
implementatie van de 'Get' te vervangen:
Registreren in PostSharp Om ervoor te zorgen dat PostSharp deze code uitvoert, moet je een 'psplugin'
schrijven. Deze hoeft niet ingewikkeld te zijn. Zie als voorbeeld hier.
Et voila Na het builden van je DLL kan je deze openen met Reflector, en zien dat de inner-method is veranderd:
There are 4 comments on this article, read them on
Coding Glamour.