Table of Contents

DataSource Configuration

you are here (click to zoom) - discover the stack

DataSources are consumed in code and in VisualQuery. In both cases they may need some configuration.

When used in code, the code will look a bit like this:

var withConfig = Kit.Data.GetSource(name: "WithConfig", parameters: new {
  AmountOfItems = 3,
  FavoriteColor = "dark blue"
});

When used in VisualQuery, the developer will specify the configuration in the UI, and the Query system will automatically transfer all the values to the DataSource.

How It Works

For all of this to work, there is a robust Configuration System. Here's how it works in summary:

  1. All properties of a DataSource which are part of the configuration are decorated using the Configuration Attribute
  2. When the object is created, the class is scanned for these attributes and a internal dictionary of all configuration values is created
  3. These configurations use Tokens - so internally it will be something like AmountOfItems = [MyConfiguration:AmountOfItems||3]
  4. If code set a new value, the token is flushed and the new value is set
  5. If a query is used, then the token part [MyConfiguration:AmountOfItems] returns what was in the data
  6. If no value is set, the fallback value is used, since [MyConfiguration:AmountOfItems] doesn't return anything

The foundation of this is built using:

  1. The Configuration Attribute and an internal loader
  2. The Configuration manager on the DataSource which helps you get the configuration
  3. The LookUp Engine which resolves any Tokens in the configuration

For it to work in VisualQuery, it also needs:

  1. A Content-Type with fields matching the property names
  2. The VisualQuery Attribute on your DataSource which references that Content-Type
  3. The internal Query Engine which provides the data on the lookup called MyConfiguration

Examples of Configurations Needed

Some of this information depends on the current context (ModuleId, UserId), others on configured settings (page size) and some on Url-parameters (Page number). In addition, we sometimes want to say "use the page-size configured in the App-Settings" or even more complex "use from url, but if not specified, try app-settings, and if that isn't defined, use 10".

How to Build a Configurable DataSource

👉 Best check the Dynamic DataSources Tutorials for some easy examples

Configuration Basics

Each configuration value of a DataSource must be a value (string, int etc.). But to allow greater flexibility in configuration, it usually starts as a string Token like [MyConfiguration:PageNumber]. This token is parsed before any data is queried using Configuration.GetThis() to convert the Token to the expected value type. Best read more about Tokens and how fallbacks, defaults and recursion work.

The Tokens allow quite some fancy features:

  1. Your DataSource will use [MyConfiguration:...] tokens and will automatically get the settings as they were added in the UI
  2. Since tokens also allow for default/fallback values, your code will often have [MyConfiguration:Id||0]
  3. As tokens are recursive, the admin can specify things like [QueryString:Id||752] in the UI and your code (asking for [MyConfiguration:Id]) will get the ID from the URL or the default 752 as the Admin specified it.
  4. Thanks to Token Stacking a lot more is possible 😉

When a DataSource is configured, it has many parameter LookUp Sources like Module, QueryString, App etc. These are shared and are identical for all objects. Read more about the LookUp Sources.

In your code you will usually not use these sources, but only use the MyConfiguration source. This source only exists in C# and contains all the values the Admin/Editor entered in the Configuration-UI. So the token [MyConfiguration:PageNumber] will deliver the number or text in the input-field pagenumber.

How Tokens are Defined, Settings Edited and Resolved

When you're using the VisualQuery designer, the configuration created is saved as an Entity (aka Content-Item) which must be injected into the DataSource configuration automatically. But when you use the object is your code, your code must be able to provide other values. But how does this work?

  1. Each DataSource object has a property called Configuration which is a dictionary containing all configuration properties the data source will care about. For example, the EntityIdFilter has a Configuration with only one property which is called EntityIds.
  2. The each property is first initialized with a Token-Template. This happens through the [Configuration] attribute. For example, the Csv DataSource has a [Configuration(Fallback = "\t")] This says that the delimiter should come from the Settings-Entity field Delimiter and if not provided, fall back to \t (which is a tab character)
  3. For the programmer who wants to set a number or whatever, this would be fairly unreliable to access from outside, so the DataSource should also have a real property which internally also modifies the dictionary. For example, the Csv DataSource has a string-property Delimiter which internally will get/set the in the Configuration dictionary.
  4. When the DataSource is first sucked from, which happens when something tries to access the Out-Property, it will automatically run a token-engine to resolve the values, then run whatever action the data-source wants.

So how does each scenario work out?

  1. If the programmer overwrote the Delimiter property, then internally the Configuration["Delimiter"] is now not a token any more, but instead just a character like ,. So the token-engine won't change anything.
  2. If the programmer didn't do anything but the VisualQuery engine gave a settings-entity to the system, then the token is resolved and whatever the user entered is used.
  3. if the neither the programmer nor the user provided settings, then the token-engine will resolve to the fallback and use the \t as was defined.

Also Read

History

  1. General Tokens introduced in 2sxc 1.0
  2. Most enhancements were in 2sxc 07.00
  3. Completely reworked in v15/16