One week ago I’ve written a post about the new “proxy app” (Microsoft.Application.app file) introduced with the 15.3 version (you can read the post here). This app uses a new property called propagateDependencies that permits you to specify whether the dependencies of this project should be propagated as direct dependencies of projects that depend on this one.
As you can imagine, this is not a property specific to this new “proxy app” but you can use it too in your extensions, but be aware of some aspects (and this is why I’ve decided to write this post).
In this demo scenario, imagine to have an extension A (your main application) that depends only on the Microsoft’s System Application and Base Application, then you need to create extension B (that depends on A and on the System Application and Base Application) and then you create extension C (that depends on A and B and also on the System Application and Base Application). A schema of the solution is represented as follows:
My extension A is a Task management system (just a fantasy app) and it’s declared as follows:
As you can see, I’ve used the propagateDependencies property set to TRUE in order to propagate the declared dependencies to other apps that depends on A. To use the propagateDependencies property you need to set “runtime”: “4.3” (version of the runtime that the project is targeting).
In this extension (just for demo purposes) I’ve declared a table object called Task, an enum object (TaskStatus) and a list page (Task List (SD)). Code is as follows:
This app A is deployed on my tenant.
Then, I create extension B as follows:
As you can see, I’ve used again the propagateDependencies property set to TRUE (to be able to propagate its dependencies) and in the dependencies block here I’ve declared the dependency only from the extension A. This is possible because A has propagateDependencies = TRUE, so you inherits also the dependencies from the standard Microsoft’s apps.
This extension B adds only a new value to the TaskStatus enum object declared on A (but in a real world you will do more than this). If you download symbols, you can see that also the standard Microsoft’s symbols are downloaded, also if not declared as direct dependencies:
Now it’s the time to create extension C. In this simple example, C will contain only a codeunit that handles the OnAfterValidate event of the Task status added on extension B and creates a new function that works on the Customer entity. Extension C (as you can see in the application diagram in the first image) must have dependencies from the standard Microsoft’s apps (System Application and Base Application) and also from A and B. But A and B have the propagateDependencies property set to TRUE, so it’s quite natural to declare C as follows:
In this way, I’m expecting that C depends on B, but B has a dependency chain where dependencies are propagated to the lowest level (B depends on A that propagates its dependencies too) and so I want to be able to see objects declared on B, on A and also on the standard Microsoft’s Base Application.
What happens if you download symbols from extension C ?
As you can see, downloaded symbols are only from extension B (direct dependency) and from extension A (propagated from B). The complete dependency chain (from A to Base Application) is not inherited here. From C, I can then work on objects declared on A and on B (see the event subscriber) but I cannot reference objects declared in the Base Application (see procedure Foo, where Customer is unknown).
To have all this working (the expected behaviour mentioned above) it’s extremely important to handle the “application” property (that permits you to specify the version of the dependent base application).
If you set this in your app.json file:
All base application’s symbols are correctly downloaded. Nice, isn’t it?