In AX4 we added Unicode support. On one hand it seems like a minor thing, it is just the storage format of strings - on the other hand it literally opens up a new world of opportunities. From a technical perspective it was a major surgical challenge; not many system files remained untouched in the process.
The same is very much true for the effort we have just completed in AX6: We have extended the ID range of concepts such as Classes, Tables, Base Enums, Extended Data Types, etc. from 16 bit to 32 bit. This certainly was a major surgical challenge; most files in the system had to be updated; still from business logic and other consumers it is still just an integer. What about the opportunities? First of all (which is very important here at Microsoft, but of little significance to everyone else) it enables Microsoft to not "run-out-of-IDs" and continue development with without disruptions. Secondly; the wider range gets us one big step closer to solving the ID problem. Now we have a range wide enough to contain solutions from various sources; we just need to figure out how to avoid conflicts between solutions other and already installed bits.
This will be the last sneak-preview for a while. We are now starting a new milestone, and I'll be back with more once I have more features to describe.
THIS POST IS PROVIDED AS-IS AND CONFERS NO RIGHTS.
If you are using the version control integration features in Dynamics AX you may be using Visual SourceSafe as the version control provider. If you do, you are probably aware that Visual SourceSafe has been in maintenance mode for several years. You may even be looking for a replacement - after all your source code is a valuable asset, and it needs a reliable and sustainable home.
Team Foundation Server (TFS) is the natural replacement offered by Microsoft - and it is also supported by Dynamics AX 2009. However, TFS has so far been two complex and too costly to be a real alternative for smaller teams.
With TFS 2010 this is changing - for more information see these two blog posts:
This is a sneak preview of two new tools in Microsoft Dynamics AX 2012: The Type Hierarchy Context and the Type Hierarchy Browser.
This video is also available on Channel 9.
About 3 years ago heading into the design phase of AX 2012 I wrote the Solving the element ID problem post. As the post describes element IDs in AX have constituted an inherent problem in all past AX releases. The problem is so fundamental that when I met with the original Axapta architects (at the Damgaard Data 25 years reunion party) they considered it insolvable without a major rewrite. In AX 2012 we did solve the problem. This post outlines the solution.
Before I dive into the solution these are our design pillars:
The solution part A - 32 bit IDs
First we needed to break the upper limit of 60.000 IDs. We decided to make IDs 32 bit (used to be 16 bit). The primary deciding factor for int32 (and not int64 or guid or str) was that there would be no X++ uptake cost of using an int32, as the int data type in X++ already is a 32 bit integer - in other words all X++ code (and table fields) handling/containing IDs would simply just continue to work untouched. In the SYS layer we have >500 fields containing IDs. Not having to convert these (e.g. to GUIDs), and provide upgrade scripts is highly desirable.
As the ID for table fields already were 32 bit (16 bit for the element ID and 16 bit for the array index) we decided to keep the field IDs as is. In other words the element ID for fields are still just 16 bit. Given these are scoped by the table, there are no upper limit concerns involved here.
Besides a lot of kernel refactoring there was one significant X++ impact. The intrinsic function TypeID had to be deprecated. It returned a 32 bit integer where the lower 16 bits contained the Type (either Types::Enum or Types:UserType), and the upper 16 bits the element ID. This function was primarily used in relation to the Dialog framework. The solutionwas to change the dialog framework to use the name of the type instead of the bit mangled integer.
The solution part B - Installation specific IDs
To solve the uniqueness problem, we need to ensure that two (or more) solutions can be implemented independently, and installed on the same system without any ID conflicts. In AX 2009 the assignment of IDs happens at creation time (i.e. when the element is created in the AOT). In AX 2012 we are deferring the assignment of IDs to installation time. This means that the model file containing the elements does not contain any element IDs. The IDs are being assigned when the model is imported by AxUtil. The consequence of this is that the same class will have different IDs on different installations. We call it "Installation specific IDs".
Caution: Deleting a model and reimporting it (or a newer version of it) will randomize IDs and thus cause data integrity issues. The right procedure when upgrading a model is to not delete the model, but just import on top of the existing model.Given the requirement to be backwards compatible we must ensure that elements released in AX 2009 (and AX 4) retained their IDs. To satisfy this requirement we introduced a new int property on all ID based elements: LegacyID, and assigned it the ID value from past releases. Now we have captured the ID the element used to have in a simple (and editable) property, and we can use it during import.
As it is vital that an element retain its ID across releases, we need to find a way to support rename scenarios. Consider the scenario where a new AX 2012 class is renamed in AX7. As the class is new it will have an installation specific ID; once the AX7 model is being imported we need to retain the ID - but if the only match criteria is the class name, and the class has been renamed, then we cannot fulfill the requirement. To solve this we introduced a new guid property on all ID based elements and all root-elements: Origin. This property is set when an element is created, and remains static for the lifetime of the elements. It is the element's fingerprint. Besides enabling invariant IDs across releases for renamed elements the Origin property has proven valuable in data export scenarios, and rename scenarios of newly fine grained meta data (like forms). This will be covered by another blog post soon.
AxUtil will during import assign IDs based on these rules:
Notice: IDs are no longer tied to layers, e.g. Layers no longer have an ID range. Nor do you need the Team Server (aka. ID Server) anymore when using a version control system.
Data can be exported from one installation to another. It is vital that any ID on the source system is mapped to the corresponding ID on the target system. The data import feature has been improved so all columns containing element IDs will be converted automatically (given they are using the proper extended data type). However; we also needed to address eventual IDs in blobs (containers). Data import and model import has no insights into the structure of the blobs. The only solution to this is to replace all ID-based element references in blobs with name-based references. We have done this for:
To solve the ID problem we had to introduce two new id properties - LegacyID and Origin. This may sound like a step in the wrong direction; however, the nature of these new properties are less restricting than that of the element ID property. In fact the only restriction on the new properties is that Origin must be unique - given Origin is a guid that is easy to satisfy. This restriction is enforced at the database level. All in all the changes outline above has been a significant investment to solve this inherent problem in the least intrusive way possible. Yet it has an impact. My next blog post will describe the impact.
The most important message is: If you are a new Microsoft Dynamics AX 2012 customer or partner, you do not need to worry (or care) about element IDs.
This is a prominent and frequently used form in the developer workspace – so shouldn’t it be sleek and user friendly?
Here is an annotated screenshot of the final result (click the image for a large version). What do you think?
Sometimes the value added by a garage-project becomes so obvious to everyone, that it must be productized. This is an example. This was literally the last developer feature that made it into AX 2012. Working in an environment where last minute changes to scope is possible despite the project’s (huge) size and extensive engineering processes is another thing I love about my job.
If you are using a version control system and want an automated build process, I have some great news for you. Microsoft has just published a beta version of CombineXPOs, which is a small utility required in the build process. For more information see here: http://blogs.msdn.com/b/axtools/archive/2012/06/29/combinexpos-new-version-official-beta-has-started.aspx
The book is now available at amazon.com. You can also browse parts of the book, including the Table of Contents at Amazon.
In the upcoming 4.0 version of C# the language now supports optional parameters – just like X++. The following is a valid method declaration in both languages:
There are a few differences between the languages with regards to optional parameters:
In X++ you can only omit optional parameters starting from the last parameter. C# makes it possible to omit any optional parameter. For example:
will call foo(5, 0, 1000).
C# doesn’t provide a way to determine, if a parameter was omitted by the caller, or the caller passed in a value identical to the default value. In X++ the prmIsDefault() method can be used to determine this. However, the use cases for this method are rare – and often fragile. For example, consider this X++ class:
Which really is terrible, as the implementation of the derived class depends on the implementation of the base class. This is bound to break eventually. Add a few more optional parameters and a few more levels of depth in the class hierarchy, and you'll have a real nightmare. My recommendation is to only use prmIsDefault() in private and final methods - as they can't be overridden. In C# you can easy live without this method, as you can achieve the same in a more robust manner using method overloading:
Yesterday at Microsoft Dynamics AX Technical Conference 2011 Peter Villadsen, Senior Program Manager gave one of his best performances ever. Anyone who have seen Peter live in the past knows what this statement carries. And it certainly didn't hurt, that Peter had excellent news to share with us.
Peter is a dear friend of mine, a top professional program manager, and a class entertainer. In his own laid-back, eloquent and well-articulated manner Peter owns the room and the audience's attention. Peter's presentation took place in the Kodiak room - the largest of the rooms we use for breakout sessions at the Microsoft Conference Center. It seats 400 people, and many more were standing along the walls - including me. Peter masters the English language to an extend where it is impossible to tell (and believe) that he is actually a native Dane. Over the course of the years I've had the pleasure of traveling with Peter to Italy, Spain and France - and I can testify that Peter also masters these dialects of the human linguistic. I do not believe it is a coincidence that Peter works in our Language team.
The session's title were: "Developing in .NET Managed Code and other X++ enhancements". Based on that title no one expected to find such fine jewels in the treasure chest. Peter started by going through some of the "minor" improvements in the X++ language in Microsoft Dynamics AX 2012. These includes:
As if the above in itself was not enough to warrant a new release - Peter moved on to the real topic: X++ as a managed languages.
The BC.NET component has been re-engineered. In Microsoft Dynamics AX 2009 it is basically a face-less client that allows the managed world to call into the AX stack. The X++ code in AX 2009 can call out into the managed world using interop. Notice that when you call out into managed code, you cannot call back into the same AX session. I.e. no round-tripping. In Microsoft Dynamics AX 2012 this is changed. The new BC.NET component is a now thin conversion layer that can attach itself (in-process) to the AX client(s), the AOS and regular managed code. It will ensure all marshaling and type conversions happen seamlessly between the two realms. Peter demonstrated this by having a X++ class pass itself to a C# class, and let the C# class change the state of the object, by invoking a method on the X++ class. It just worked exactly like you would expect.
But wait - there is even more. In Microsoft Dynamics AX 2012 we are compiling X++ code to the CLR. At compile time we generate an XML representation of the pcode, which we can convert into IL. At run-time we will be executing the IL for batch jobs, service calls and RunAs constructs. (RunAs is a new method allowing you to request the X++ logic to be executed as IL.). Peter demonstrated how the performance characteristics are vastly different particular in situations with extremely many objects or extremely many methods calls. Even in less-extreme situations running X++ as IL is beneficial as for example it reduces the time database locks are held, and thus improves performance and scalability.
Peter started the session by quoting Bob Dylan's The Times They Are A-changin' - I believe everyone in the audience agreed.
Wrapping up Microsoft Dynamics AX Technical Conference 2011 Deepak Kumar, Senior Program Manager, presented the data upgrade framework in Microsoft Dynamics AX 2012.
Data upgrade is an intrinsic difficult subject to demonstrate in a breakout session. “Seeing is believing”, and Deepak had invested the time in preparing no less than six AX instances each at a different stage in the data upgrade process. With this setup Deepak was able to demonstrate all the improvements at various points in the data upgrade process. I’ve had the pleasure of presenting with Deepak a few times in the past. I know how much attention he pays to detail, and how much time he spends preparing just his slideshow. With this setup I will not even guess how much time Deepak has invested in helping us understand the data upgrade process in AX 2012. As one of the 400+ attendance in the audience, I felt I got spoiled. Thank you Deepak!
“Fear – Challenged – Rewarded – Joy” is the emotional evolution you go through during the data upgrade process.
Fear is the naturally emotion that kicks in when you are facing a big unknown change. To reduce the fear an Upgrade Readiness tool will be available. You install this tool on your live AX 4 / 2009 system. The tool offers a lot of benefits. First, it enables you to verify that the data in your live system can be upgrade. For example, if an optional column is being converted to an mandatory column, and your current production data has <blank> contents in the field – then the data upgrade is bound to fail. In the past you discovered issue like this much later in the process – you could call it trial-n-error. This pre-verification allows you to fix your data on your live production system before starting the actual upgrade.
Challenged replaces fear, as you now know you are in good hands. The Upgrade Readiness tool will secondarily enable you to enter data that is required to run AX 2012. In the past you would be entering this type data after the actual data upgrade but still during the downtime. Now you can enter the data up-front while the system is live. It is a quite comprehensive amount of data you need to provide, covering global address book, site, financial dimensions, organizational model etc. Next the live Preprocessing allows you to process live data to a staging area. It will be doing data transformations in the process, and the idea is to lower the complexity (and thus execution time) for the upgrade scripts that needs to run during the downtime. This process is of course delta-based, so any updates happening in the live system can be reapplied to the staging area. You can even control how much of your live system’s resources should be used for this, e.g. you may only want to use 0% during peak hours, 20% during night time, and 40% in the weekends.
On the AX 2012 installation you can connect to the live production system. The upgrade process now prioritize the actual upgrade scripts and data copy tasks based on the data composition of the production data you have. You can of course tweak the prioritization of the upgrade scripts and data copy tasks to further tune your data upgrade. At this point you have completed about 80% of the data upgrade process, and now is the time to take the system offline to do the actual data copy/transformation. Reward is in sight.
True joy is when the upgrade is completed, and you uninstall the upgrade model. The upgrade model contains all the DEL_ tables/fields/indexes, and as you don’t need them anymore – you might as well remove them completely from your system. This way your developer experience on the system gets much improved. Take a look here:
Let me wrap up my coverage of the Microsoft Dynamics AX Technical Conference 2011 with a quote I heard yesterday: “AX is like Hotel California – once you get there, you can never leave!”