Showing posts with label Reflection. Show all posts
Showing posts with label Reflection. Show all posts

Friday, January 29, 2010

Wie man die Modifier Private, Protected und Abstract umgeht

Auf Wunsch der Leserschaft werden meine Beiträge nun auch in deutscher Sprache veröffentlicht. Dieser Post bezieht sich auf den englischsprachigen Post How to ignore Private, Protected and Abstract modifiers. 

Bisher habe ich mich immer über die Meldungen "Statisches Konstrukt implementieren, um Änderungen zu ermöglichen." und "'New' muss den Status 'protected' aufweisen." gewundert.

Sagen wir, wir möchten eine neue Verarbeitung mit einer RunBaseBatch-Klasse realisieren: Wenn wir nun den Optimalen Verfahren folgen, werden wir folglich die new()-Methode Protected deklarieren. Aber wie soll nun das Framework der Stapelverarbeitung jemals ein Objekt aus dieser Klasse erstellen, sollte der Benutzer die Verarbeitung in den Stapel stellen?

Weil die new()-Methode ja nun mit dem Modifier Protected geschützt ist, kann aus der Klasse kein Objekt mit new() erstellt werden, richtig?
Theoretisch ja, allerdings hat man da die Rechnung ohne die Möglichkeiten der Reflection-Technik in AX gemacht.

Wie im Allgemeinen bekannt, ist es möglich mit dem Kernelobjekt vom Typ DictClass (oder mit dem vielleicht besser bekannten abgeleiteten Typ SysDictClass) dynamisch Objekte zu erstellen und Objektmethoden aufzurufen. Nach ein paar Tests hat sich herausgestellt, dass das DictClass Objekt seinen ganz eigenen Regeln folgt, wenn es um die Möglichkeiten der Codeverarbeitung geht.

Mit einem DictClass-Objekt kann man Objekte aus Klassen erstellen, die dafür gar nicht geeignet sind. So kann man mit der makeObject()-Methode:
  • Objekte aus abstrakten Klassen erzeugen 
  • Objekte erstellen auch wenn die new()-Methode Private oder Protected deklariert ist (die new()-Methode wird dann auch wirklich durchlaufen) 
  • Objekte erstellen, auch wenn die jeweilige Klasse nicht alle abstrakten Methoden überschrieben hat 
Aber die Möglichkeiten mit dem DictClass-Objekt enden nicht einfach damit verbotene Objekte zu erstellen. Es ist auch möglich:
  • Member- und statische Methoden ungeachtet der Modifier protected, private oder abstract aufzurufen (mit callObject() und callStatic()
Als wäre das nun nicht schon genug der Blasphemie: das DictTable-Objekt verfügt ebenfalls über diese Verhaltenseigenschaften. Mit callStatic() und callObject() des DictTable-Objektes kann jede beliebige Tabellenmethode aufgerufen werden.

Fazit: In AX existieren zwar hässliche, aber äusserst effektive Verfahren um Codesicherheit und Kompilerprüfungen zu umgehen. Auch wenn es möglich ist, diese Tricks einzusetzen, rate ich dringend davon ab. Dieser Artikel soll nur zeigen was möglich ist, das heisst aber nicht, dass es auch sinnvoll ist.

(Inhalt bezieht sich auf AX 2009)

Tuesday, December 22, 2009

How to ignore Private, Protected and Abstract modifiers

I was always curious about the Best Practices messages "Implement static construct to allow for modifications." and "New should be protected."


Say, you want to create a new class derived from RunBaseBatch; if you follow the Best Practice warnings (as named above), your new()-method will be declared Protected. But how the Batch Framework can create an object from this class if the user decide to let that process run in batch mode?


Since the new()-method is protected, the object cannot created with that method, right? Theoretical yes, but do not underrate Reflection Technique in Dynamics AX.

As known, you can create objects and invoke methods on it, using an object of the kernel class DictClass (or its even more popular derivate SysDictClass). The DictClass object seems to be very powerful and follows its own rules of code execution abilities.

With a DictClass object you can create objects what theoretically not should be possible. Use the makeObject()-method and you can:
  • Create objects from classes which are abstract
  • Create objects from classes even the new()-method is declared as Private or Protected (the code execution really runs through the new()-method)
  • Create objects from classes which have not implemented all abstracted methods from the super class

But the power of the DictClass objects does not just end with creating other objects. You are also able to invoke:
  • Member and static methods despite protected, private or abstract modifier (callObject() and callStatic())

As if this wasn't enough, the DictTable object shares that behavior property too. You can invoke any table method you want by calling the callStatic()- or callObject()-method on the DictTable object.


You see, there are dirty tricks to leverage AX's code security and compiler checks. Even it is possible to do such things, I really recommend to avoid executing theoretical illegal operations as mentioned. This article just shows what is possible and not what make sense :)

(all content relates to AX 2009)