I will start now, sorry for a small delay. I want to continue my topic. The first part was dedicated to creating rules for code check, in other words best practices. Microsoft has a list of standards for code and metadata that enable making code more high quality, predictable and comprehensible. There are two types of rules. The first one is for checking metadata (tables, forms, extended data types). The second one is for checking code rules, that is checking business logic created with X++ language. In the first part of my presentation I told about how to get access to Dynamics 365 code and metadata. Now data is stored in XML files. Now, there are many ways to get and analyze data. Microsoft uses these techniques for analyzing the code written by partners. They do not recommend using overlaying but create extensions instead. By autumn, it is planned to restrict the possibility of modifying the main Application Suite model, so the code will be extended using extensions methodology only. Microsoft uses partners’ solutions to see how much the code is changed with overlaying by partners in order to insert the necessary entry points and delegates or expand metadata extension capabilities. Based on previous knowledge, we will try to create a real code check rule today and see how the code check creation framework works on real example. To create a new code check rule, we need to use Common Best Practice Framework which allows a developer not to analyze and parse the code. It provides a programmer with the infrastructure so that they could see what restrictions they need to create for a certain rule. In Axapta 2012, Best Practice code was written in X++, and now it’s C#. To access metadata, we can use either DICT classes or a new framework with more extensive metadata access support. DICT classes are left for compatibility purposes and can get metadata only in old understanding, for example they cannot get information about extensions, which can be done only with a new framework. Common Best Practice Framework uses this library to analyze the code and metadata. This framework provides us with Source Code Parser and ready parsed abstract code tree that can be used to analyze the code structure. Code takes form of a tree consisting of class, methods as branches, parameters and variables as leaves. It provides us with a conveyor to go over all the objects that participate in code check launched during compilation. All the objects participating in compilation stage will be transferred to Best Practice Framework to analyze the code and display diagnostic notifications if this code is not compliant with certain rules. This framework also provides us with the metadata extracting infrastructure. The main root of the framework is ST Visitor class that implements Visitor template. It is required for circumventing trees as it provides us with the infrastructure to run certain code on every leaf of the tree. ST Visitor class in Axapta contains many methods circumventing a tree. When we visit a statement, we analyze if it’s a “while” statement or a simple one and enter the “while”. If we circumvent an abstract tree of some class, for example, the root of this tree will contain a class declaration and leaves will contain the methods. To be able to analyze structure of some method, we need to redefine virtual “Visit” method. When Best Practice enters this method, it will run the code that will perform the analysis. When visiting a “While” statement, the method will be called “VisitWhileStatement”. So, if you need to analyze “While” statement, you will have to redefine “VisitWhileStatement” method. Payloads can be transferred to these methods. This is additional user data that you need to transfer between many methods, for example, Axapta version. You can inherit from Payload object to this parameter. Let’s try to implement the simplest inheritor of ST Visitor class. It will calculate parameters in the method, total number of parameters and parameters starting with an underscore sign. We inherit from AstVisitor class, create two properties, ParameterCount and UnderscoreParameters. In these properties, the number of method parameters will be stored, and in UnderscoreParameters, the number of underscore parameters will be stored. Now, we need to redefine VisitMethodParameters method that will be called anytime the Best Practice framework goes over parameters of some method in the abstract tree. We increment the value of Count parameter with the value of the number of parameters in the method. Here, so-called LINQ is used. We take the number of parameters with the names starting from the underscore. This way we can easily implement a logic that will calculate the number of parameters in a method. Framework provides us with full infrastructure to think about how to circumvent a tree, which methods to call. VisitMethodParameter will be called each time. If we want to enter a method, we need to redefine VisitMethod. As we circumvent a tree, we may not know that VisitMethod may need to continue running the standard code in order to go over method abstract tree if it’s been implemented. Instead of Return, Super is called, and the framework calls standard methods that will be called in parameter method. By calling Return, we stop the processing in this tree sheet, framework returns to the upper level and goes over the tree. We can optimize this way. If we only need to calculate the number of parameters in VisitMethod class without analyzing their types, we can just stop the processing and optimize the working time of Best Practice Framework. The first thing we need to do to create a rule is to understand what and how this rule will be checking. Also, we need to determine which message will be displayed for the user as a lot depends on it. In the first CTP versions, many Best Practices displayed the messages that were totally incomprehensible. Best Practice Framework enables full customization of the message that will be displayed to the user during compilation, which will help the user to fix this Best Practice quicker. Let’s try to create a new rule. Often, several people work in one project. In order to find who did certain actions, you need to perform many analyses, go to version control system and if, for example, a class has been modified for one hundred times, it will be hard to find the author of the method. I suggest creating an attribute that enables specifying the author of each method and class. Let’s create this project now, I will call the method “AuthorAttribute”. It is inherited from SysAttribute. The variable will be private. We’ll redefine the constructor in order to be able to transfer parameters. This way we will specify the author. A project always contains a certain list of people. By running a Best Practice check, I want to find out if the person specified in the attribute is the same as the project list of people. Let’s see the implementation of this rule in C#. In order to create a Best Practice rule, a project template can be used (File – New project – Best Practice Rules Template). It will provide the structure of the project with examples of using the code quality and metadata checks. This is an example of checking metadata (see screen). AuthorListRule class uses the logic of the Best Practice rule. In order to circumvent a tree, we use AstVisitor class. Best Practice AstChecker class inherits from AstVisitor and implements additional methods. We can transfer the type, so-called payloads, additional data that we can use as user data. First, we define the list of people involved in the project. This is me and my colleagues, Vitalii and Viktoriia. Next, we redefine the VisitMethod that will be called each time the Best Practice framework circumvents an abstract tree and comes across a method. We want to see the attributes attached to this method and analyze the data in this attribute. This is a new framework that appeared in AX 7 and enables referring to metadata in a more convenient way. ForEach is a simple loop that goes over all the attributes of the method. [comment from the audience] Sorry. We take the value specified in this attribute (see screen) and get it as a literal value. Then, we add the list of names specified in this attribute to the local list. As we know, we can apply one attribute to a method or a class several times. Next, we check if this list in the attributes corresponds to the list defined above. If not, a diagnostic notification will appear where the class (inherited from custom diagnostic item where we send detailed information about an error) is implemented. There was an error, so the notification contains its symbol name. It can also include some required information, such as the fact that the author specified in this attribute is not on the list. Let’s try to compile this project and install it in Visual Studio. We have compiled a binary file and beside it, there is a file that we can use for debugging this rule. We need to put it all to this folder (see screen). Having put these files here and re-launched Visual Studio, they will appear in the options automatically. Once again, we have created Author class attribute and a class for which we specified this attribute in Class Declaration. The compilation is launched, and this rule must work, as “Ivan” is not on the list of the names. The rule is not on the error list. Can anyone guess why? Let’s open this project. So, what can be the problem? If we take a closer look, we will see that we redefined the VisitMethod, so we are looking for the attribute in the methods. Let’s remedy the error. We can write a Class Declaration method with the same check logic. It is not as impressive as iPhone 8 presentation. It must work now as it’s a method. Let’s write a name from this list. [question from the audience] If it’s not there, we will not go over the ForEach loop. Completed, the name is allowed. We can debug Best Practice rules with at least two Visual Studios, one with the source code of this rule and another to launch code compilation in order to launch Best Practice Framework. To start debugging, we need to put DBD file with debug information to the same folder. In debug, XPP compiler process will be attached. It must work now. We entered a method and its view in form of an abstract tree. The list of attributes, comments, method attributes, declaration. Abstract tree provides with a whole path to analyze the code. We go over attributes and may check any of them further. This is everything I wanted to tell. In any class there is an invisible Constructor New method. When I was developing URL, it entered NEW method, and Visit method was called twice, and now it’s called once.