The original method, referred to as overlayering, involved making a copy of the modified object in a higher layer – usually VAR or CUS – and then simply using that object instead. While very simple to implement, it seriously complicated patching. Any change to the object at a lower layer would simply be ignored and a code merge was required to bring in new functionality. Microsoft streamlined this by providing automated code merging functionality, but there was no way to guarantee it would all work without some kind of review.
Which brings us to extensions. Extensions are not a new concept in software development – or even to the AX family for that matter. Originally introduced in AX 2012, extensions started as event handlers. If you are still on AX 2012 and would like to read up on event handlers, https://msdn.microsoft.com/en-us/library/gg839762.aspx is a great starting point. Essentially, in the most common implementation, you created an event handler that subscribed to a method. You could have the event handler trigger either before (pre) or after (post) the method code.
This new way of thinking about AX code opened a lot of possibilities, not the least of which was using C# or managed code as an event handler. The whole idea around it was really to allow developers to write code that would be update-proof. Since the base object was not overlayered, any patches would be included without a code merge and without affecting custom code. It didn’t remove the need for regression testing, that should be done whether custom code is involved or not, but it did remove the need for a code merge.
Unfortunately, the availability of event handlers was very limited and it didn’t help with changes that didn’t involve methods, like new fields or security objects. In Dynamics 365 for Operations, this issue has been resolved because all objects now subscribe to the extension methodology. This does mean that there is not a one to one comparison between AX 2012 event handlers and Dynamics 365 for Operations extensions. For methods, the parallel is there, but for tables and other non-method objects, it works a little differently. The best analogy I can think of when describing extensions is traditional animation using cells. If you are not familiar with the technique, you can read about it here. Basically, you create several individual images that get stacked together to create a complete picture, but you never change one image to affect another.
The net result of using extensions is that base objects are never modified. This allows Microsoft to apply patches that can take effect immediately without the need of a code merge. The need for code compares and the potential for code merges doesn’t disappear completely because it is possible to have multiple extensions on a base object. An example of this would be an ISV modifying a table that is also modified by internal developers.
It’s important to point out that overlayering is still available on some objects in Dynamics 365 for Operations, but Microsoft has already begun the process of locking code down so that it cannot be overlayered. If you attempt to overlayer a locked object, your compile will fail. Eventually all code will be locked out, the last I heard the full lockdown will be completed by July of 2018. This should be visible at some point on the Dynamics 365 roadmap which you can watch here. For those considering an upgrade, this is significant. It means that at some point in your upgrade process code that modifies base objects will need to be converted to the extension model. The upgrade tool for AX 2012 will automate some of this, however it will not be able to refactor it all. For AX 2009, there is no code upgrade path, it will all need to be reviewed/rewritten.
To start using extensions, you will first need to understand the changes made to models. Models are still design time collections, however if you create a new model it will only have access to the objects it contains unless you add references. If you create a model and find out that you need to add a reference, that is not an issue, you can just update the model definition. Again, the concept of references is not new and anyone who has used any of the Visual languages will be familiar with it. It is worth the effort of reviewing all the out of the box references to make sure you understand the overall functionality included in each of them. Below is a screen shot of the reference selection screen from the new model creation wizard. Note that simply adding all of the reference is a possibility, but not recommended as it results in larger deployment packages and the possibility if unintended dependencies.
With the decision made on the model you will be using, you can set it as the default so all new modifications (extensions and net-new objects) will use that model.
Now that you are ready to start developing, creating new code works the same as in AX 2012, but the visual studio interface lays things out a little differently. Navigating Visual Studio is beyond this blog, however there are a lot of tutorials out there on how to use VS.
Step one is still to create a project (file -> new project). To add objects to a project, simply right click on the project and select Add -> new item. The AOT objects are listed in the Operations Artifact list (image below). Select the one you need, give it a name and click add.
To modify an existing object, find it in the AOT, right click on it and select Create extension. Note that some of the objects in the AOT have been grouped a little differently, so if you don’t find what you are looking for, keep at it, they are all there.
This will add the object to your current project. If you want to add it to a new project, that option is there as well. The object will be added to your project with an Extension suffix as in the image below.
Start working with it by right clicking it and selecting Open or by simply double clicking it.
Once you have the objects in place that you need to work with, the development process is very much the same. X++ hasn’t changed so you can still write the same code that you always have. On any new objects, we can add fields, set properties, override methods and add methods just like always. Working with existing objects is the same, except for methods. For example, if I wanted to add a field to the InventTable, I right click on the Fields node in my Extension object and select add field. I don’t have the same option for methods. Methods in Dynamics 365 for Operations follow along the event handler paradigm introduced in AX 2012. So to extend an existing method, I would need to create an event handler and link it in. Existing methods allow me to add a pre- or post- event handler, but if I need to add a new method, it needs to be tied to an event.
Events are things that happen in AX that Microsoft has exposed for developer use. Taking a look at a sample of the events on the InventTable we see options like those in the image below.
We use these events by creating a new class that will run our code and then copying the event handler method into our code. This keeps the original object intact but allows us to run our code where we need to. For example, to add code when a record in the InventTable is about to be deleted, I create a new class in my project, then copy the onDeleting event handler and paste it into my class:
I can then add my code in this method. Notice that I have access to the DataEventArgs so I can see what record deletion is being requested. I can work with this information to do additional validation or take action on other tables. In the case of a validation error, if I throw an exception the delete will not occur.
From my perspective, the biggest hurdle in moving to Dynamics 365 for Operations development isn’t so much figuring out how, but where. Not being able to change methods inline is going to force us all to think a little differently about the execution steps performed in a process. It also means that there are some modifications that won’t fit in to the event handler model. If the code really needs to happen inline and there is no available event, then overlayering will still be required. Microsoft is aware of this, which is why they have not completely locked out code. The good news is they are working on how to fix this. In the meantime, even though overlayering is still an option we should start moving all code to code to the extension model until we run into a situation where overlayering is the only option. This will make it a much smoother transition when overlaying is no longer available.
Obviously, this is a quick and dirty look at how to get started, just scratching the surface on how to change gears for working in Dynamics 365 for Operations. There are several other great resources out there offering tutorials and deeper-dive descriptions on a lot of this, hopefully this will help give you an idea on where you to where you need to focus.
Here are a few links to get you started on a deeper dive.
If you have any stories or examples of code that you have already migrated, I would love to hear them. Drop me a line at firstname.lastname@example.org or look me up on linked in at https://www.linkedin.com/in/scottmorley541/