Table of Contents

Module dependencies

Neos modules have been designed to be distributed and used in several clusters as dependencies.
This distribution is for the moment manual but for it to work the module must be autonomous.
The module can only use what it or one of the modules it depends on has defined. A module can only work correctly if all the modules on which it depends are present.
On the other hand, the absence of a module on which it does not depend must not impact its operation.
This concept is similar to what you will find in the dependencies of a Visual Studio project, an NPM package or a Nuget package.

How to define dependencies between modules?

In the module edit screen, you can manage its dependencies in the Dependencies tab. All modules on which a module depends should be listed here.

How to check metadata dependencies?

Starting with Neos 1.10, metadata dependencies are checked automatically when saving in Neos Studio.
When the module of a metadata is modified, the saving process will attempt to automatically propagate/fix the module of all the dependent metadata.

Warning

You will see the result of the propagation/fixing only after saving.

Default behaviour

The default behavior is to attempt to propagate the new module on dependencies whose key contains the key of the parent metadata.

For example, if you modify the module of an entity view CustomerView, the module change will be propagated on all the parameters, properties and validation rules configured for this entity view. This is because entities of type EntityViewParameter, EntityViewProperty and EntityViewValidationRule all contain the name of the entity view they depend onto in their key.
The change will not be propagated to the UI views referencing the CustomerView entity view because the entities of type UIVIew do not contain an entity view name in their key.

This rule, which may seem complicated at first glance, means that in most cases the propagation is limited to the data you can enter on the screen.

Furthermore, the module of a dependent entity is only updated when :

  • the module of the dependent entity is the same as the original module of parent entity

or

  • the module of the dependent entity becomes invalid because it does not depend on the new module of the parent entity

Forcing propagation to all dependent entities

In some cases, you may want to propagate module changes to all dependant entities without limitation. This can be done using with the following line (still in the YAML configuration of your cluster):

ModuleUpdateBehavior: Cascade
Warning

It is advisable to make a backup of your cluster before changing a module because the changes can be very important.

Note

The updated configuration is taken into account immediately, there is no need to restart Neos Studio.

In our previous example, when changing the module on the CustomerView with the Cascade behaviour would this time also update the module on the UI view referencing it.

Disabling propagation

It is possible to completly disable the propagation by adding the following line to the YAML configuration of your cluster:

ModuleUpdateBehavior: NoAction

How to control dependencies in C# code?

There is currently no automatic check for C# code proposed by neos. The only way to be sure that a module can work only with its dependencies is to perform a generation on a cluster that contains only the modules in question.

How to ignore dependency errors?

Although this is not generally recommended, it is possible to ignore metadata-related errors.
It may be necessary in the following cases:

  • Following the switch to Neos 1.10 to allow time to fix dependency errors that were not reported before.
  • When moving large amounts of metadata between modules, the dependency check may prevent you from making the moves gradually.

Module dependency errors are identified by the N102 error code. It is possible to ignore them by adding the following line in the YAML configuration of your cluster:

YamlIgnoredErrors: [102]

How to fix existing dependency errors?

To find all the existing errors on a cluster, use the check-metadata command.

Warning

The neos check-metadata command takes the cluster configuration into account, do not forget to remove the N102 error from your YAML configuration file.

How to create dependencies between .NET business code projects of different modules?

A business code project should look like this:

<Project Sdk="Microsoft.NET.Sdk">
  <Import Project="../build/NeosReferences.Domain.gen.props" />
  ...
</Project>

You can use Visual Studio to create a reference from a business project in module B to a business project in module A. If module B is directly in the modules folder, then the project will look like this:

<Project Sdk="Microsoft.NET.Sdk">
  <Import Project="../build/NeosReferences.Domain.gen.props" />
  ...
  <ItemGroup>
    <ProjectReference Include="..\..\..\A\businessAssembly\Domain\A.Domain.csproj" />
  </ItemGroup>
  ...
</Project>

However, if module B is in the modules/dependencies folder, then the project will look like this:

<Project Sdk="Microsoft.NET.Sdk">
  <Import Project="../build/NeosReferences.Domain.gen.props" />
  ...
  <ItemGroup>
    <ProjectReference Include="..\..\..\dependencies\A\businessAssembly\Domain\A.Domain.csproj" />
  </ItemGroup>
  ...
</Project>

If your A module will never be distributed and used as a dependency in another cluster, you can leave your references like this.

However, if your B module is to be distributed, it will end up in the modules/dependencies folder at the same level as the A module. The path ..\..\..\dependencies\A\businessAssembly\Domain\A.Domain.csproj will become invalid, because the B module will be searched for in modules/dependencies/dependencies (rather than modules/dependencies).

To solve this problem, neos generates properties with the path of each parent module in the standard imported props file. These properties are named {ModuleName}ModuleDirectory. The previous example can be updated to read as follows:

<Project Sdk="Microsoft.NET.Sdk">
  <Import Project="../build/NeosReferences.Domain.gen.props" />
  ...
  <ItemGroup>
    <ProjectReference Include="$(AModuleDirectory)\businessAssembly\Domain\A.Domain.csproj" />
  </ItemGroup>
  ...
</Project>

With the use of $(AModuleDirectory), the reference will be correct when module A is at the same level as module B and also when it is in a dependencies subfolder.