In my first two posts on models in AX (Part 1 and Part 2) I covered the deployment specific behaviors of .axmodel files - it should be apparent we introduced .axmodel files as a deployment replacement for AOD files. In the process we added some nice capabilities like a manifest and signing. The real benefit of models, and the ultimate reason we are adding this level of abstraction is because:
You can have as many models per layer as you want.
Let us examine this statement. In AX2009 a layer is the confinement unit of model elements. The layer is the unit of which you can export, deploy and delete model elements. (Here I'm deliberately ignoring the capabilities provided by XPO files, as these are suitable for development purposes only, and not deployment.) In AX6 this limitation has been removed, that means you can segment your layer into as many models as you like.
Here are a few examples where this could be useful in development scenarios:
- If you deliver more than one solution:
You can have a model for each of the solutions you are working on. This enables you to work on them simultaneously while having visibility into which model you are working on.
- If your solution is getting too big:
You can segment your solution into several models - and have teams/team members work on their own model. The models can be either self-contained or have dependencies to other models. This enables you to clearly define ownership between the models, clearly define the APIs between the models, build the models individually, etc.
- If you write unit test:
You can have a model for your production code and a model for your unit tests. This enables you to easily import all your unit tests, run them, and remove them again from the system.
Let's examine the statement a bit deeper. There are two ways of getting a model: Either you create one on your own, or you receive it from someone else. If you can have as many models as you want per layer, it also means:
You can deploy models from several sources into the same layer.
Here is an example: You are a customer and would like to install two ISV solutions that both are available in the BUS layer. In AX2009 you would have a tough choice to make: Either you picked your favorite solution and learned to live without the other one, or you invested in having the two solutions merged into one layer. This merge is technical challenging, and a costly affair once updates to either solution are being released. In AX6, however, you download the two models, and use AxUtil to import them. When a new version of either model is released, you simply use AxUtil to update the model.
This all sounds too good to be true, what is the downside? There is one limitation to what a model can contain:
An element can only be defined once per layer.
This means that two models containing a definition of the same element cannot be installed in the same layer. For example; if the two models both contain a class named: "MyClass" they will not be able to install side-by-side in the same layer. Model elements have two alternate keys, they are: [Type, Parent, ID] and [Type, Parent, Name]. Each layer can only contain elements that can uniquely be identified via the two alternate keys. In less technical terms, this means that two elements of same type under same parent (or without a parent) cannot co-exist if they have same name or same ID. For example: A table cannot have two fields with same name, or two fields with same ID. Another example: You cannot have two display menu items with the same name.
There are three ways you can be hit by this limitation:
- You create an element, and give it a name that accidentally also has been chosen for another element by someone else in their model. A good way to avoid this to prefix your new elements with short string that uniquely identify you or your company. So instead of me naming my class "MyClass" I should name it "MfpMyClass". You can think of this as poor-man's namespaces. This is a practice that is already widely used.
- You create an element that will be assigned an ID by the system, which already has been assigned to another element created by someone else in their model. Our plan is that this cannot occur once we ship AX6 - we are close to a full implementation of this, but we are not there yet. I'll return with more details on this at a later point.
- You customize an existing element that also has been customized by someone else in their model. There is really nothing you can do to avoid this collision, except to avoid customizing - which is not desirable nor possible. To alleviate this problem we are investing in changing the granularity of elements. In AX2009 tables and classes are stored with a fine granularity. This means that there is no collision if two models change two different methods on the same class or table. In AX6 all new concepts introduced in the model will also use a fine granularity - further we are breaking down some of the existing concepts, so far we have completed this work for Menus.
So apparently we cannot guarantee that models can co-exist in the same layer - so what are the options when two models are in conflict? When you import a model that conflicts with an already imported model, you get three options:
- Push-up (default)
This option creates a new model in layer above containing the conflicting elements. This enables you to log into this layer and resolve the conflicts using the MorphX tools you are used to. Please notice that only the few elements in-conflict will be moved into this model, so the resolutions required are limited, and the original models will co-exist in the model store - but not only in the same layer.
For example; if two models ("ModelA" and "ModelB") are imported into the BUS layer, then "ModelA" is imported without any problems, and "ModelB" will be imported into two models: "ModelB" in the BUS layer, and "ModelB_Conflicts" in the BUP layer.
This option will overwrite any existing definitions with the definitions in the new model. Any model containing element definitions that get overwritten will be logically grouped with new model. The grouping ensure that an eventual uninstall of a model doesn't leave the system in an in-complete state. This option is primary useful for patches that are accumulative in nature.
For example; If a model "ModelA" containing PatchA is already installed, and a new model "ModelB" containing PatchA+B is being installed then this is the right option. Later; if "ModelB" is being uninstalled, then "ModelA" is also automatically uninstalled.
This option aborts the operation and leaves the model store untouched - perhaps you specified the wrong model file, perhaps you want to investigate the models before continuing.
Models enable a lot of highly desirable scenarios, one of the most important scenarios being that models from different sources - for example, two ISVs - can be installed in the same layer side-by-side. There are a few technical limitations; but the risk of conflicts is much reduced in AX6 and even when conflicts occur there is a less-expensive way to make the models co-exist.
More on models...
This post is a part of a series on models:
This posting is provided "AS IS" with no warranties, and confers no rights.