Collator - Accessing the Data System from Code

The Collator class is the main gateway for all calls to the data API.  It and all collator classes must implement the ICollator interface.  Lynicon core includes the ContentCollator and the BasicCollator.  There is also the BaseCollator that both of these inherit from and it may be easier to inherit from this than build an entirely new ICollator if creating a custom collator.

Collator is a singleton, it propagates calls to the specific collators registered for different content types according to the parameters of each call.

When specifying the type to return, these calls support using parent types and interfaces, including object, as a way of representing that content of a group of different types should be returned.  The data returned can then be cast to the appropriate type to perform operations associated with that type.

Methods

Getting Data

T Get<T>()
T Get<T, TContent>()

This simply gets all content records stored whose type can be assigned to type T. If T is a summary type, it returns all the summaries that can be assigned to that type.  The second cast works as the first, except only records whose content type is TContent are returned.  This is useful for e.g. to get the summaries for a specific content type.

T Get<T>(RouteData rd)
T Get<T>(Type contentType, RouteData rd)

For a given request, when processed into RouteData, this method returns the content item of type T associated with it.  If no content item has been created which is associated with this request, null is returned.

If T is a generic list, this will return a list of data associated with the request.  To some extent, OData style filtering and paging is supported on this kind of request: the results returned will be filtered/paged as specified by the argument in rd.

The second signature allows for specifying the content type required: this allows for T to be a summary type.

T Get<T>(Address address)
IEnumerable<T> Get<T>(IEnumerable<Address> addresses)

The Address class is an intermediary representation which can be extracted from either a url (in the form of RouteData) or an actual content item to uniquely identify it in terms of its natural url address.  These methods return the content item or items found at an address or addresses.

T can be a content type to return content items, or a summary type to return summaries, in which case any item whose summary is not assignable to T will be ignored.

T Get<T>(ItemId id)
IEnumerable<T> Get<T>(IEnumerable<ItemId> ids)

The ItemId class contains a unique record identifier plus a type, so it will uniquely identify any content item available from the data API.  ItemVersionedId inherits from ItemId and can be used in these methods to further specify the version of the content item required.

These methods return the content item or items with the id or ids supplied.

T can be a content type to return content items, or a summary type to return summaries, in which case any item whose summary is not assignable to T will be ignored.

IEnumerable<T> Get<T, TQuery>(Func<IQueryable<TQuery>, IQueryable<TQuery>> queryBody)
IEnumerable<T> Get<T, TQuery>(IEnumerable<Type> types, Func<IQueryable<TQuery>, IQueryable<TQuery>> queryBody)

These methods use a query to return a number of content items.  In order to be able to internally compose the query from any data source, the query argument is specified as a mapping from the data source IQueryable to the data output IQueryable.  An example would be iq => iq.Where(x => x.Name = "tim").

T here is the type returned by the API. TQuery is the type to which you are applying the queryBody.  This can be the relevant container type or a content type.  It may be depending on caching that if the the content type is used, all the records of the given type may need to be loaded from the database which will be very inefficient if there are a lot.

In the second case, the query is run across the data sources for all the types assignable to the 'types' parameter.  In the first case, all types which can be assigned to T are used.

Changing Data

bool Set(object data)
bool Set(object data, bool? create)
bool Set(Address address, object data)
bool Set(Address address, object data, bool? create)
bool Set(Address address, object data, bool? create, bool bypassChecks)
bool Set(Address address, object data, Dictionary<string, object> setOptions)

The above calls are used to update or create a content item.  Generally the second type is only needed where the data object has no attached record of its metadata, and therefore the API does not know at what address to save it.  Inheritors fromBaseContent will have their metadata attached and so do not need an address supplied.

Additional flags can be used.  The API will infer whether to create or update the record based on whether its Id is the default value (Guid.Empty for guids).  If the create flag however is present and not null, it will use this indication instead.

The bypassChecks flag should be set in order to act directly on the API without the mediation of modules which can alter the action actually taken on the data source for their own purposes, and without consistency and error checking.  This should only be used with care as it can make data inconsistent and code incompatible with certain modules.  Generally it is only used in module code.

Other flags specific to modules can be set using the signature with the setOptions parameter.

The bool value returned is whether the item was added as a new content item.

void Delete(object data)
void Delete(Address address, object data)
void Delete(Address address, object data, bool bypassChecks)

These calls work similarly to Set, but delete the relevant data item. Again the bypassChecks flag can be set to avoid alteration of the call by modules or blocking by consistency and error checking.