Working with Source XML
Introduction
The attribute-driven customization of source objects in Code Effects is highly effective. However, there are scenarios where you may not have a concrete .NET class at design time, or you want full control over the authoring structure — for example, in multilingual scenarios or when you prefer not to rely on class reflection. In such cases, a declarative XML representation of your source object - called Source XML - is a viable alternative.
Why Use Source XML?
You might choose Source XML for any of the following reasons:
- You want to skip the reflection process and reuse the same source definition across multiple sessions or HTTP requests.
- You need to present fields, in-rule methods, and actions in different languages and want to externalize display text.
- You need precise control over the metadata that the Rule Editor uses, beyond what reflection allows.
Why use Source XML instead of Adaptive Source?
The Source XML option is ideal when you need to dynamically shape the Rule Editor's available fields and methods before the editor is initialized, but do not require Adaptive Source's ability to build each rule interactively based on its current authoring context. For example, an application can generate Source XML on the fly - using AI, user roles, tenant settings, external configuration, or any other runtime criteria - to expose only the elements relevant to a particular user or scenario. This approach provides much of the flexibility of a dynamic source model while preserving the simplicity of the traditional editor initialization process.
The trade-off is that the entire generated source becomes available to the editor from the start of rule authoring, rather than evolving dynamically as the rule itself is being constructed. As a result, features that depend on continuous context awareness during authoring, such as Context Resetting, are not available when using the Source XML option.
How to Create Source XML
You can create a Source XML document in one of two ways:
Generate from an existing .NET class — Set the SourceType of a Control to your class, then call GetSourceXml() to extract the XML. Since version 7, the static Control.GetSourceXml(Type) does the same without a Control instance, and Control.GetSourceXml(ISourceProvider) writes the whole source of an Adaptive Source provider. Edit and validate the XML against the schema, then store it (file system, database) for reuse.
using CodeEffects.Rule.Editor;
var editor = new Control("divEditorContainer") { SourceType = typeof(MySourceClass) };
string sourceXml = editor.GetSourceXml();
// Or, without an editor instance
string sameXml = Control.GetSourceXml(typeof(MySourceClass));
Create manually from scratch — Author the XML document based on the published schema instead of generating it via reflection. This offers full control. The Xml class can help you get an empty SourceXML document:
using System.Xml;
using CodeEffects.Rule.Editor.Utils;
string sourceSchemaLocation = Xml.SourceNamespace;
XmlDocument sourceXml = Xml.GetEmptySourceDocument();
Loading Source XML into the Rule Editor
Once you have a valid Source XML document, you can configure the Rule Editor to use it instead of a class:
using System.Xml;
using CodeEffects.Rule.Editor;
string sourceXmlString = YourStorage.GetSourceXmlSomehow();
var sourceXml = new XmlDocument();
sourceXml.LoadXml(sourceXmlString);
var editor = new Control("divEditorContainer")
{
SourceXml = sourceXml
};
Alternatively, you can use the Control.SourceXmlFile property to specify a file path.
Multilingual and Variant Use-Cases
In applications supporting multiple languages/cultures, you may maintain separate Source XML documents per culture. Each document sets DisplayName and/or Description attributes for fields, in-rule methods, and actions in the target language. At runtime you load the appropriate version.
Important Considerations
- Source XML must adhere to the specified schema. The schema is versioned by its namespace, and the current one is
https://codeeffects.com/schemas/source/7, which Xml.SourceNamespace returns. The editor still reads documents of the earlier versions. Version 7 added the displayName attribute of the <source> node, the <enums> section with the members of every enumeration the document uses, the <references> section with the labels of reference-type properties, and timeType.
- Generic methods (methods with generic parameters) cannot be used in Source XML as in-rule methods or rule actions. Use a .NET class instead for those.
- If you later switch from Source XML to a corresponding .NET class (or vice-versa), ensure consistency of field, method, and action names so that stored rules remain valid.
- For multilingual scenarios, maintain consistent IDs or field names across culture variants to avoid authoring errors when switching.
In the Rule Repository
The Rule Repository (RR) stores every source as Source XML, whatever form it arrived in: a Source XML document, a .NET type, and an Adaptive Source provider are each converted to a document before RR compares and stores them. You give RR your documents with SourceSettings.SourceXmls, and RR's editors always run on the stored document:
using CodeEffects.Rule.Repository;
var settings = new SourceSettings();
settings.SourceXmls.Add(sourceXmlString);
SyncResult result = Context.SyncSources(dbProvider, settings);
- The alias is the
type attribute of the first <source> node, with the assembly identity removed. Documents with the same alias describe the same source object, and the alias should never change.
- One definition per source object. If a document matches the stored version except for labels, such as display names and descriptions, RR replaces the stored document with the new one and does not create a version. Any other difference creates a new source version. So RR does not keep a document per language of one source: the labels you sync last are the labels RR shows. Translating the text of RR itself is a separate feature.
- Several definitions of the same alias in one call are a way to give an empty repository a history it never had. That is not repeatable, because each call would find the stored version different from the first document and add more versions, so guard it with
Context.GetAliasNames.
- Types that a document names (enumerations, data sources) must load when RR reads it. Set
SourceSettings.TypeResolver for types that have aliases or live in assemblies that your application does not load by name.
- Source XML cannot carry Context Resetters. See Context Resetters.
Summary
Using Source XML gives you full control of the authoring surface for the Rule Editor - allowing you to define available fields, methods, actions, and display names externally, without relying solely on reflection of classes. It is especially useful when a class is unavailable, when you need variant sources, or when you require multilingual labeling.