logo
logo

Strongly typed entities

Since version 3.1 the SDK supports strongly typed entities. Strongly typed entities can be seen as extensions or wrappers for the base IEntity, specifically for one type of entities.

Strongly typed entities are still an IEntity, but the entity's members are also provided as C# properties and methods for a better development experience. Since strongly typed entities are still an IEntity, they can still be used with the entities client, the querying client and other clients.

Some examples of strongly typed entities are IAsset for "M.Asset" entities and IMailTemplate for "M.Mailing.Template" entities.

Under this index there will be a complete list of strongly typed entities supported in the SDK. This article focuses on the general usage of strongly typed entities.

Inheritance

All strongly typed entities are derived from ITypedEntity, which itself derives from IEntity.

Design

Strongly typed entities provide some entity members as C# properties. Take for example IAsset, which has the following property:

string FileName { get; set; }

The implementation of this such properties is very simple. The getter basically does this:

return asset.GetPropertyValue<string>("FileName");

And the setter is implemented like this:

asset.SetPropertyValue("FileName", value);

They are mostly shortcuts, and relations are handled similarly. However, sometimes strongly typed entities expose more than simply getting or setting property and relation values.

Usage

To use strongly typed entities, we must first get an instance of that strongly typed entity. Sometimes this strongly typed entity will be directly returned from a client, like Task<IMailTemplate> GetMailTemplateAsync(...) on the notifications client. Otherwise a cast will be necessary.

While the entities client returns all entities as IEntity, a downcast is advised if you know for sure that the entity is of the specified entity definition. Even the entity factory will create the right strongly typed instance, if there is one.

For example, when we are sure that the entity with the id 1000 is an asset, the following snippet can be used to retrieve the entity:

IAsset asset = await MClient.Entities.GetAsync(1000) as IAsset;

Then the filename can be retrieved in the following way:

string filename = asset.FileName;

Partial entities

Partial entities are entities that are not fully loaded. By default, the SDK loads entities only partially: only the default culture, with all properties but no relations. By passing the load configurations, this behavior can be changed.

When a property or a relation is not loaded, the SDK returns null when getting the property values or an empty collection on some relations. When trying to set a property value using IEntity on a property that is not loaded, the SDK throws an exception about the missing property.

This behavior is the same on strongly typed entities. When an asset is loaded without properties and we try to get the filename in the following way:

string filename = asset.FileName;

Then filename contains null, even if the asset has a value on the server. This happens because the FileName property was not loaded.

To prevent this problem, always make sure to load the entity with the members you will be using. Additionally, ITypedEntity instances support the LoadTypedMembersAsync method. This method will lazy load all the members that are exposed on the strongly typed interface. This has more overhead though, and should therefore be used wisely.

Warning

Strongly typed assets only work when their definition's members are not modified. For example, if the FileName property on the M.Asset definition is renamed, this method will no longer work. However, it would still be possible to get the value from the IEntity methods.

Can we improve this article ? Provide feedback