update XML IO pattern.

This commit is contained in:
2026-05-24 14:06:51 +08:00
parent 058003f395
commit d7836db45f
314 changed files with 13376 additions and 573 deletions
@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Class XFactory | HiAPI-C# 2025 ">
<meta name="description" content="Factory class for generating objects from XML elements using registered generator functions.">
<meta name="description" content="Factory for generating objects from XML elements using registered generator functions.">
<link rel="icon" href="../img/HiAPI.favicon.ico">
<link rel="stylesheet" href="../public/docfx.min.css">
<link rel="stylesheet" href="../public/main.css">
@@ -97,12 +97,13 @@ Class XFactory
<dl><dt>Assembly</dt><dd>HiGeom.dll</dd></dl>
</div>
<div class="markdown summary"><p>Factory class for generating objects from XML elements using registered generator functions.</p>
<div class="markdown summary"><p>Factory for generating objects from XML elements using registered generator
functions.</p>
</div>
<div class="markdown conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public static class XFactory</code></pre>
<pre><code class="lang-csharp hljs">public class XFactory</code></pre>
</div>
@@ -144,11 +145,57 @@ Class XFactory
</div>
</dd></dl>
<dl class="typelist extensionMethods">
<dt>Extension Methods</dt>
<dd>
<div>
<a class="xref" href="Hi.Common.DuplicateUtil.html#Hi_Common_DuplicateUtil_TryDuplicate__1___0_System_Object___">DuplicateUtil.TryDuplicate&lt;TSelf&gt;(TSelf, params object[])</a>
</div>
<div>
<a class="xref" href="Hi.Common.InvokeUtil.html#Hi_Common_InvokeUtil_SelfInvoke__1___0_System_Action___0__">InvokeUtil.SelfInvoke&lt;TSrc&gt;(TSrc, Action&lt;TSrc&gt;)</a>
</div>
<div>
<a class="xref" href="Hi.Common.InvokeUtil.html#Hi_Common_InvokeUtil_SelfInvoke__2___0_System_Func___0___1__">InvokeUtil.SelfInvoke&lt;TSrc, TDst&gt;(TSrc, Func&lt;TSrc, TDst&gt;)</a>
</div>
<div>
<a class="xref" href="Hi.Coloring.ColorUtil.html#Hi_Coloring_ColorUtil_GetGloomyColor_System_Object_System_Double_System_Double_">ColorUtil.GetGloomyColor(object, double, double)</a>
</div>
<div>
<a class="xref" href="Hi.Common.NameUtil.html#Hi_Common_NameUtil_GetSelectionName_System_Object_">NameUtil.GetSelectionName(object)</a>
</div>
<div>
<a class="xref" href="Hi.Common.StringUtil.html#Hi_Common_StringUtil_GetPropertyStringIfToStringNotOverloaded_System_Object_System_Boolean_System_Boolean_">StringUtil.GetPropertyStringIfToStringNotOverloaded(object, bool, bool)</a>
</div>
<div>
<a class="xref" href="Hi.Parallels.LockUtil.html#Hi_Parallels_LockUtil_Lock_System_Object_">LockUtil.Lock(object)</a>
</div>
</dd></dl>
<h2 id="Hi_Common_XmlUtils_XFactory_remarks">Remarks</h2>
<div class="markdown level0 remarks"><p>Generator functions must be added to <a class="xref" href="Hi.Common.XmlUtils.XFactory.html#Hi_Common_XmlUtils_XFactory_Generators">Generators</a> to enable the factory to create objects from XML.</p>
<div class="markdown level0 remarks"><p>
Each <a class="xref" href="Hi.Common.XmlUtils.XFactory.html">XFactory</a> instance owns its own <a class="xref" href="Hi.Common.XmlUtils.XFactory.html#Hi_Common_XmlUtils_XFactory_Generators">Generators</a>
registry. A process-wide <a class="xref" href="Hi.Common.XmlUtils.XFactory.html#Hi_Common_XmlUtils_XFactory_Default">Default</a> singleton serves the common
case (single shared factory across the simulation pipeline); other instances
can be created for test isolation or parallel pipelines that need disjoint
registries.
</p>
<p>
Types that participate in XML round-trip expose a
<code>public static void Reg(XFactory factory = null)</code> method that adds
themselves (and chains <code>Reg(factory)</code> on dependents) to the given
factory's <a class="xref" href="Hi.Common.XmlUtils.XFactory.html#Hi_Common_XmlUtils_XFactory_Generators">Generators</a>. Boot roots (e.g.
<code>LocalProjectService.Reg()</code>) call the top-level <code>Reg()</code> once at
startup with the default factory.
</p>
<p>
The static <code>Gen&lt;T&gt;</code> / <code>GenByChild&lt;T&gt;</code> /
<code>GenByFile&lt;T&gt;</code> entry points always read from
<a class="xref" href="Hi.Common.XmlUtils.XFactory.html#Hi_Common_XmlUtils_XFactory_Default">Default</a>. Callers that need to deserialize from a custom
factory's registry must look up the delegate via
<code>factory.Generators[xname]</code> directly.
</p>
</div>
@@ -156,6 +203,40 @@ Class XFactory
</h2>
<a id="Hi_Common_XmlUtils_XFactory_Default_" data-uid="Hi.Common.XmlUtils.XFactory.Default*"></a>
<h3 id="Hi_Common_XmlUtils_XFactory_Default" data-uid="Hi.Common.XmlUtils.XFactory.Default">
Default
</h3>
<div class="markdown level1 summary"><p>Process-wide default factory used by the static <code>Gen&lt;T&gt;</code>
family. Reg-style methods register here when called with
no explicit factory argument.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public static XFactory Default { get; }</code></pre>
</div>
<h4 class="section">Property Value</h4>
<dl class="parameters">
<dt><a class="xref" href="Hi.Common.XmlUtils.XFactory.html">XFactory</a></dt>
<dd></dd>
</dl>
<a id="Hi_Common_XmlUtils_XFactory_Generators_" data-uid="Hi.Common.XmlUtils.XFactory.Generators*"></a>
<h3 id="Hi_Common_XmlUtils_XFactory_Generators" data-uid="Hi.Common.XmlUtils.XFactory.Generators">
@@ -163,12 +244,13 @@ Class XFactory
</h3>
<div class="markdown level1 summary"><p>Gets or sets the dictionary mapping XML element names to generator functions with relative file path.</p>
<div class="markdown level1 summary"><p>XML-name → generator-function map for this factory instance. Populated
by each type's <code>Reg(this)</code> call.</p>
</div>
<div class="markdown level1 conceptual"></div>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public static Dictionary&lt;string, XFactory.XGeneratorDelegate&gt; Generators { get; set; }</code></pre>
<pre><code class="lang-csharp hljs">public Dictionary&lt;string, XFactory.XGeneratorDelegate&gt; Generators { get; }</code></pre>
</div>
@@ -199,8 +281,7 @@ Class XFactory
</h3>
<div class="markdown level1 summary"><p>Generates an object of type T from the first child element of the provided XML element.
This overload discards the relative file path output.</p>
<div class="markdown level1 summary"><p>Generates an object of type T from the first child element (discards relative file path).</p>
</div>
<div class="markdown level1 conceptual"></div>
@@ -261,37 +342,29 @@ This overload discards the relative file path output.</p>
<h4 class="section">Parameters</h4>
<dl class="parameters">
<dt><code>src</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.xml.linq.xelement">XElement</a></dt>
<dd><p>The parent XML element containing the child to process</p>
</dd>
<dd></dd>
<dt><code>baseDirectory</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.string">string</a></dt>
<dd><p>The base directory for resolving paths</p>
</dd>
<dd></dd>
<dt><code>relFile</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.string">string</a></dt>
<dd><p>Output parameter that receives the relative file path if src is a file reference, or null otherwise</p>
</dd>
<dd></dd>
<dt><code>progress</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.iprogress-1">IProgress</a>&lt;<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object">object</a>&gt;</dt>
<dd><p>Progress reporter for the XML parsing chain</p>
</dd>
<dd></dd>
<dt><code>enableRebase</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd><p>Whether to rebase the directory to the file's location</p>
</dd>
<dd></dd>
<dt><code>res</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object">object</a>[]</dt>
<dd><p>Additional parameters for generation</p>
</dd>
<dd></dd>
</dl>
<h4 class="section">Returns</h4>
<dl class="parameters">
<dt><span class="xref">T</span></dt>
<dd><p>The generated object of type T, or null if src is null</p>
</dd>
<dd></dd>
</dl>
<h4 class="section">Type Parameters</h4>
<dl class="parameters">
<dt><code>T</code></dt>
<dd><p>The type of object to generate</p>
</dd>
<dd></dd>
</dl>
@@ -321,34 +394,27 @@ This overload discards the relative file path output.</p>
<h4 class="section">Parameters</h4>
<dl class="parameters">
<dt><code>baseDirectory</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.string">string</a></dt>
<dd><p>The base directory for resolving paths</p>
</dd>
<dd></dd>
<dt><code>relFile</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.string">string</a></dt>
<dd><p>The relative file path to the XML file</p>
</dd>
<dd></dd>
<dt><code>progress</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.iprogress-1">IProgress</a>&lt;<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object">object</a>&gt;</dt>
<dd><p>Progress reporter for the XML parsing chain</p>
</dd>
<dd></dd>
<dt><code>enableRebase</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd><p>Whether to rebase the directory to the file's location</p>
</dd>
<dd></dd>
<dt><code>res</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object">object</a>[]</dt>
<dd><p>Additional parameters for generation</p>
</dd>
<dd></dd>
</dl>
<h4 class="section">Returns</h4>
<dl class="parameters">
<dt><span class="xref">T</span></dt>
<dd><p>The generated object of type T, or null if relFile is null</p>
</dd>
<dd></dd>
</dl>
<h4 class="section">Type Parameters</h4>
<dl class="parameters">
<dt><code>T</code></dt>
<dd><p>The type of object to generate</p>
</dd>
<dd></dd>
</dl>
@@ -367,7 +433,7 @@ This overload discards the relative file path output.</p>
</h3>
<div class="markdown level1 summary"><p>Generates a <a class="xref" href="Hi.Common.XmlUtils.FileRefSource-1.html">FileRefSource&lt;T&gt;</a> from the first child element of the provided XML element.</p>
<div class="markdown level1 summary"><p>Generates a <a class="xref" href="Hi.Common.XmlUtils.FileRefSource-1.html">FileRefSource&lt;T&gt;</a> from the first child element.</p>
</div>
<div class="markdown level1 conceptual"></div>
@@ -517,8 +583,7 @@ This overload discards the relative file path output.</p>
</h3>
<div class="markdown level1 summary"><p>Generates an object of type T from an XML element.
This overload discards the relative file path output.</p>
<div class="markdown level1 summary"><p>Generates an object of type T from an XML element (discards relative file path).</p>
</div>
<div class="markdown level1 conceptual"></div>
@@ -529,34 +594,27 @@ This overload discards the relative file path output.</p>
<h4 class="section">Parameters</h4>
<dl class="parameters">
<dt><code>src</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.xml.linq.xelement">XElement</a></dt>
<dd><p>The source XML element</p>
</dd>
<dd></dd>
<dt><code>baseDirectory</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.string">string</a></dt>
<dd><p>The base directory for resolving paths</p>
</dd>
<dd></dd>
<dt><code>progress</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.iprogress-1">IProgress</a>&lt;<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object">object</a>&gt;</dt>
<dd><p>Progress reporter for the XML parsing chain</p>
</dd>
<dd></dd>
<dt><code>enableRebase</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd><p>Whether to rebase the directory to the file's location</p>
</dd>
<dd></dd>
<dt><code>res</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object">object</a>[]</dt>
<dd><p>Additional parameters for generation</p>
</dd>
<dd></dd>
</dl>
<h4 class="section">Returns</h4>
<dl class="parameters">
<dt><span class="xref">T</span></dt>
<dd><p>The generated object of type T</p>
</dd>
<dd></dd>
</dl>
<h4 class="section">Type Parameters</h4>
<dl class="parameters">
<dt><code>T</code></dt>
<dd><p>The type of object to generate</p>
</dd>
<dd></dd>
</dl>
@@ -575,7 +633,7 @@ This overload discards the relative file path output.</p>
</h3>
<div class="markdown level1 summary"><p>Generates an object of type T from an XML element.</p>
<div class="markdown level1 summary"><p>Generates an object of type T from an XML element using <a class="xref" href="Hi.Common.XmlUtils.XFactory.html#Hi_Common_XmlUtils_XFactory_Default">Default</a>.</p>
</div>
<div class="markdown level1 conceptual"></div>
@@ -586,37 +644,29 @@ This overload discards the relative file path output.</p>
<h4 class="section">Parameters</h4>
<dl class="parameters">
<dt><code>src</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.xml.linq.xelement">XElement</a></dt>
<dd><p>The source XML element</p>
</dd>
<dd></dd>
<dt><code>baseDirectory</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.string">string</a></dt>
<dd><p>The base directory for resolving paths</p>
</dd>
<dd></dd>
<dt><code>relFile</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.string">string</a></dt>
<dd><p>Output parameter that receives the relative file path if src is a file reference, or null otherwise</p>
</dd>
<dd></dd>
<dt><code>progress</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.iprogress-1">IProgress</a>&lt;<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object">object</a>&gt;</dt>
<dd><p>Progress reporter for the XML parsing chain</p>
</dd>
<dd></dd>
<dt><code>enableRebase</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.boolean">bool</a></dt>
<dd><p>Whether to rebase the directory to the file's location</p>
</dd>
<dd></dd>
<dt><code>res</code> <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.object">object</a>[]</dt>
<dd><p>Additional parameters for generation</p>
</dd>
<dd></dd>
</dl>
<h4 class="section">Returns</h4>
<dl class="parameters">
<dt><span class="xref">T</span></dt>
<dd><p>The generated object of type T</p>
</dd>
<dd></dd>
</dl>
<h4 class="section">Type Parameters</h4>
<dl class="parameters">
<dt><code>T</code></dt>
<dd><p>The type of object to generate</p>
</dd>
<dd></dd>
</dl>