Table of Contents

Class TypeMap

Namespace
ActivityPub.Types
Assembly
ActivityPub.Types.dll

Implements a "type graph", which is a form of emulated multiple inheritance. This adapts the ActivityStreams dynamic type model to the C# static type model.

[JsonConverter(typeof(TypeMapConverter))]
public class TypeMap
Inheritance
TypeMap
Inherited Members

Constructors

TypeMap()

Constructs a new, empty type graph initialized with the ActivityStreams context.

public TypeMap()

TypeMap(ITypeGraphReader)

Constructs a TypeMap from a JSON message

internal TypeMap(ITypeGraphReader sourceJson)

Parameters

sourceJson ITypeGraphReader

TypeMap(JsonLDContext)

Constructs an empty TypeMap from pre-constructed context. The caller is responsible for populating any associated entities.

internal TypeMap(JsonLDContext ldContext)

Parameters

ldContext JsonLDContext

Remarks

This constructor is required to convert links in string-form. That specific case is not supported by TypeGraphReader.

Fields

_asTypes

private readonly CompositeASType _asTypes

Field Value

CompositeASType

_entityCache

private readonly Dictionary<Type, ASEntity> _entityCache

Field Value

Dictionary<Type, ASEntity>

_ldContext

private readonly JsonLDContext _ldContext

Field Value

JsonLDContext

_modelCache

private readonly Dictionary<Type, ASType> _modelCache

Field Value

Dictionary<Type, ASType>

_sourceJson

private readonly ITypeGraphReader? _sourceJson

Field Value

ITypeGraphReader

Properties

ASTypes

AS type names that are represented by this object, excluding those that have been shadowed. The returned object is a live, read-only view of the collection. Changes will be reflected immediately.

public IReadOnlySet<string> ASTypes { get; }

Property Value

IReadOnlySet<string>
See Also

AllASTypes

AS type names that are represented by this object, including those that have been shadowed. The returned object is a live, read-only view of the collection. Changes will be reflected immediately.

public IReadOnlySet<string> AllASTypes { get; }

Property Value

IReadOnlySet<string>
See Also

AllEntities

Live map of .NET types to loaded entities contained in this graph. This may be a subset or superset of ASTypes.

public IReadOnlyDictionary<Type, ASEntity> AllEntities { get; }

Property Value

IReadOnlyDictionary<Type, ASEntity>
See Also

LDContext

JSON-LD context that describes this object. This returns a live instance that will be automatically updated whenever the graph is extended.

public IJsonLDContext LDContext { get; }

Property Value

IJsonLDContext

UnmappedProperties

Properties that exist in the JSON, but did not map to any properties.

[JsonInclude]
[JsonExtensionData]
public Dictionary<string, JsonElement>? UnmappedProperties { internal get; set; }

Property Value

Dictionary<string, JsonElement>

Methods

AddEntity(ASEntity)

Like TryAddEntity(ASEntity), but throws if a conflicting entity already exists in the map.

internal void AddEntity(ASEntity instance)

Parameters

instance ASEntity

Exceptions

InvalidOperationException

If an object of this type already exists in the graph

AsEntity<TModel, TEntity>()

Gets an entity representing the object as entity type

TEntity
.
public TEntity AsEntity<TModel, TEntity>() where TModel : ASType, IASModel<TModel, TEntity> where TEntity : ASEntity<TModel, TEntity>, new()

Returns

TEntity

Type Parameters

TModel
TEntity

Remarks

This function will not extend the object to include a new type. To safely convert to an instance that might be present, use IsEntity<TModel, TEntity>(out TEntity?).

Exceptions

InvalidCastException

If the object is not of type

TEntity
See Also

AsModel<TModel>()

Gets an object representing the graph as model type

TModel
.
public TModel AsModel<TModel>() where TModel : ASType, IASModel<TModel>

Returns

TModel

Type Parameters

TModel

Remarks

This function will not extend the object to include a new type. To safely convert to an instance that might be present, use IsModel<TModel>(out TModel?).

Exceptions

InvalidCastException

If the graph cannot be represented by the type

See Also

Extend<TModel, TEntity>()

Extends the TypeGraph to include a new entity. The entity must have a parameterless constructor. Throws an exception if the entity would be a duplicate or have unmet dependencies.

public TEntity Extend<TModel, TEntity>() where TModel : ASType, IASModel<TModel, TEntity> where TEntity : ASEntity<TModel, TEntity>, new()

Returns

TEntity

Type Parameters

TModel
TEntity

Remarks

This function cannot accomodate entities with required members. Instead, Extend<TModel, TEntity>(TEntity) must be used.

Exceptions

InvalidOperationException

If the entity type already exists in the graph

InvalidOperationException

If the entity requires another entity that is missing from the graph

See Also

Extend<TModel, TEntity>(TEntity)

Extends the TypeGraph to include a new entity. Throws an exception if the entity would be a duplicate or have unmet dependencies.

public TEntity Extend<TModel, TEntity>(TEntity entity) where TModel : ASType, IASModel<TModel, TEntity> where TEntity : ASEntity<TModel, TEntity>, new()

Parameters

entity TEntity

Returns

TEntity

Type Parameters

TModel
TEntity

Exceptions

InvalidOperationException

If the entity type already exists in the graph

InvalidOperationException

If the entity requires another entity that is missing from the graph

See Also

IsEntity<TModel, TEntity>()

Checks if the object contains a particular entity type.

public bool IsEntity<TModel, TEntity>() where TModel : ASType, IASModel<TModel, TEntity> where TEntity : ASEntity<TModel, TEntity>, new()

Returns

bool

Type Parameters

TModel
TEntity

IsEntity<TModel, TEntity>(out TEntity?)

Checks if the object contains a particular type entity. If so, then the instance of that type is extracted and returned.

public bool IsEntity<TModel, TEntity>(out TEntity? instance) where TModel : ASType, IASModel<TModel, TEntity> where TEntity : ASEntity<TModel, TEntity>, new()

Parameters

instance TEntity

Returns

bool

Type Parameters

TModel
TEntity
See Also

IsModel<TModel>()

Checks if the graph contains a particular model type.

public bool IsModel<TModel>() where TModel : ASType, IASModel<TModel>

Returns

bool

Type Parameters

TModel
See Also

IsModel<TModel>(out TModel?)

Checks if the graph contains a particular model type. If so, then the instance of that model is extracted and returned.

public bool IsModel<TModel>(out TModel? instance) where TModel : ASType, IASModel<TModel>

Parameters

instance TModel

Returns

bool

Type Parameters

TModel
See Also

NarrowUnmappedProperties(ASEntity)

private void NarrowUnmappedProperties(ASEntity entity)

Parameters

entity ASEntity

ProjectTo<TModel, TEntity>(bool)

Projects the type graph into a specific type of entity. If

extendGraph
is true, then a new instance is constructed and linked to the graph. Otherwise, an existing instance is returned.
public TEntity ProjectTo<TModel, TEntity>(bool extendGraph) where TModel : ASType, IASModel<TModel, TEntity> where TEntity : ASEntity<TModel, TEntity>, new()

Parameters

extendGraph bool

Returns

TEntity

Type Parameters

TModel
TEntity

Remarks

This function cannot accomodate entities with required members. Instead, Extend<TModel, TEntity>(TEntity) must be used.

Exceptions

InvalidOperationException

If

extendGraph
is true and the entity type already exists in the graph
InvalidOperationException

If

extendGraph
is true and the entity requires another entity that is missing from the graph
InvalidCastException

If

extendGraph
is false and the object is not of type
TEntity
See Also

TryAddEntity(ASEntity)

Adds a new typed instance to the graph. Metadata such as AS types and JSON-LD context is automatically updated. User code should not call this method; use Extend<TModel, TEntity>() instead.

internal bool TryAddEntity(ASEntity entity)

Parameters

entity ASEntity

Returns

bool

true if the type was added, false if it was already in the type map

Remarks

This method is internal as it has strict semantics regarding its use. This is not a technical limitation, but rather an intentional choice to prevent the construction of invalid objects. It is possible to induce confusing runtime crashes if a required entity is skipped.

For example, imagine that there is an empty TypeMap called "map". The following calls are made:

  • map.AddEntity(new ASTypeEntity())
  • map.AddEntity(new ASActivityEntity())
  • map.AsModel<ASActivity>()
The last call will throw an InvalidCastException stating that the graph cannot be represented as ASObjectEntity. This can be extremely hard to diagnose because ASObjectEntity does not even appear in the visible code.

The Extend<TModel, TEntity>() function, however, avoids this with an included dependency check. The second call to AddEntity(ASEntity) will fail with a descriptive error message indicating that

Object
is missing from the graph. While still somewhat confusing, this method will additionally fail fast before the graph can even enter an invalid state. This ensures that errors are caught quickly and before they can spread to corrupt the application state.
See Also