deploy webservice static-file routing for docsite folder URLs, per-instance step-cache db, and constant-height panel title bars.

This commit is contained in:
2026-08-27 14:51:37 +08:00
parent 1fc510af5e
commit 2a98ae7556
1468 changed files with 182837 additions and 18888 deletions
@@ -152,15 +152,15 @@ public static void Reg(XFactory factory = null)
}
</code></pre>
<h3 id="iprogress-threading">IProgress Threading</h3>
<p>The <code>IProgress&lt;object&gt;</code> parameter is threaded through the entire deserialization chain. When a class constructor calls <a class="xref" href="../../api/Hi.Common.XmlUtils.XFactory.html">XFactory</a> to deserialize child objects, it passes the same <code>progress</code> instance:</p>
<p>The <code>IProgress&lt;IMessage&gt;</code> parameter is threaded through the entire deserialization chain. When a class constructor calls <a class="xref" href="../../api/Hi.Common.XmlUtils.XFactory.html">XFactory</a> to deserialize child objects, it passes the same <code>progress</code> instance:</p>
<pre><code class="lang-csharp">public MyClass(XElement src, string baseDirectory, string relFile,
IProgress&lt;object&gt; progress)
IProgress&lt;IMessage&gt; progress)
{
Child = XFactory.GenByChild&lt;IChild&gt;(
src.Element(nameof(Child)), subBaseDirectory, progress);
}
</code></pre>
<p>Parsing errors are reported to the caller-provided <code>IProgress&lt;object&gt;</code> handler.</p>
<p>Parsing errors are reported to the caller-provided <code>IProgress&lt;IMessage&gt;</code> handler.</p>
<h2 id="boot-path">Boot path</h2>
<p>An application's entry point (web service <code>Program.cs</code>, WPF <code>App.xaml.cs</code>, test fixture, etc.) must call the appropriate top-level <code>Reg()</code> once at startup, before any project XML is deserialized. For the simulation pipeline this is:</p>
<pre><code class="lang-csharp">LocalProjectService.Reg();
@@ -336,7 +336,7 @@ public XElement MakeXmlSource(string baseDirectory, string relFile, bool exhibit
<li><strong>Registration</strong>: Expose <code>public static void Reg(XFactory factory = null)</code>; first line is <code>factory ??= XFactory.Default;</code> then <code>factory.Generators.TryAdd(XName, …)</code>.</li>
<li><strong>Chain dependents</strong>: For every concrete type T that the ctor reads via <code>XFactory.Gen&lt;T&gt;</code> / <code>XFactory.GenByChild&lt;T&gt;</code>, add <code>T.Reg(factory);</code> to the chain. For polymorphic <code>GenByChild&lt;IInterface&gt;</code>, chain every implementation that the XML may carry.</li>
<li><strong>Idempotent</strong>: Use <code>TryAdd</code>, never <code>Add</code>. The same <code>Reg</code> is called from many boot paths.</li>
<li><strong>Progress Threading</strong>: Pass the <code>IProgress&lt;object&gt;</code> parameter through all nested <code>XFactory</code> calls. See <a href="message-management.html">Message Management</a> for the rationale.</li>
<li><strong>Progress Threading</strong>: Pass the <code>IProgress&lt;IMessage&gt;</code> parameter through all nested <code>XFactory</code> calls. See <a href="message-management.html">Message Management</a> for the rationale.</li>
<li><strong>Legacy Support</strong>: Register the canonical <code>XName</code> first, then group aliases under a <code>//legacy aliases</code> comment.</li>
<li><strong>Derived class registration</strong>: When a derived class needs its own <code>Reg</code>, mark it <code>public new static void Reg(XFactory factory = null)</code> so the C# compiler does not warn about hiding the base method.</li>
</ol>