Working With Channels in iModels

A "channel" is a tree of models and elements below a Channel Subject element. Channels segregate the contents of an iModel into sections to provide access control over which applications may change which data. The concept is cooperative in that applications indicate the channels to which they pertain, and any attempt to modify data outside one of those channels is denied with a channel constraint exception at runtime.

To help visualize how channels are used, imagine an iModel with the following breakdown:

RootSubject

  • DictionaryModel

    • Elements ...
  • Subject0

    • PhysicalPartition01
      • Model01
        • Elements ...
  • Subject1

    • PhysicalParition11
      • Model11
        • Elements ...
  • Subject2

    • PhysicalParition21
      • Model21
        • Elements ...
    • Subject21
      • PhysicalParition211
        • ...

In this example, Subject1 and Subject2 are the channel roots. All of the elements and models under them are in their respective channels. Color-coding is used to identify each tree. Everything in red is in Subject1's channel. Everything in blue is in Subject2's channel.

Not everything in an iModel is in a channel. Everything that is not below a Channel Subject is considered part of the Shared Channel. The Shared Channel may be modified by all applications. In the diagram above, everything in black is in the Shared Channel.

ChannelKeys

Every channel has a channelKey that is used for controlling write access to it.

Note: channelKey is distinct from the Code of the Channel Subject element. It is a key chosen by the application that creates a channel and is not visible to the user. More than one Channel Subject may use the same channelKey.

ChannelControl

Every IModelDb has a member IModelDb.channels of type ChannelControl that supplies methods for controlling which channels are editable during a session.

The method ChannelControl.getChannelKey will return the channelKey for an element given an ElementId.

Allowed Channels

The ChannelControl member of an IModelDb holds a set of allowed (i.e. editable) channels. Any attempt to add/delete/update an Element, ElementAspect, or Model whose channelKey is not in the set of Allowed Channels will generate a ChannelConstraintViolation exception.

After opening an IModelDb but before editing it, applications should call ChannelControl.addAllowedChannel one or more times with the channelKey(s) for which editing should be allowed. To stop editing a channel, call ChannelControl.removeAllowedChannel.

For example:

    imodel.channels.addAllowedChannel("structural-members");

Later, to disallow editing of that channel call:

    imodel.channels.removeAllowedChannel("structural-members");

Note: The "shared" channel is editable by default, so it is automatically in the set of allowed channels. To disallow writing to the shared channel, you can call imodel.channels.removeAllowedChannel("shared")

Creating New Channels

To create a new Channel Subject element (and thereby a new channel), use ChannelControl.insertChannelSubject.

E.g.:

  imodel.channels.insertChannelSubject({ subjectName: "Chester", channelKey: "surface-stubs" });

Generally, Channel Subject elements are created as an child of the Root Subject. However, insertChannelSubject accepts an optional parentSubjectId argument so that Channel Subjects can appear elsewhere in the Subject hierarchy. However, channels may not nest. Attempts to create a Channel Subject within an exiting channel will throw an exception.

Channels vs. Locks

Locks and Channels are orthogonal concepts. To edit an element, its channel must be allowed AND its lock must be held.

Each is possible without the other:

  • If another user holds the lock on an element, editing is denied even though it is an allowed channel.
  • An element may have been edited in a previous session or by another application in the same session. In that case the lock may be held, but further edits are denied if its channel is not allowed.

Last Updated: 15 March, 2023