This repository has been archived on 2026-10-11. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
HiNC-2025-win-desktop-Deploy/App/wwwroot/HiAPI-docsite/anatomy/by-source/webservice-backend.html
T
2026-09-11 03:46:11 +08:00

301 lines
18 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Web Service Backend Source Tree | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Web Service Backend Source Tree | HiAPI-C# 2025 ">
<link rel="icon" href="../../img/HiAPI.favicon.ico">
<link rel="stylesheet" href="../../public/docfx.min.css">
<link rel="stylesheet" href="../../public/main.css">
<meta name="docfx:navrel" content="../../toc.html">
<meta name="docfx:tocrel" content="toc.html">
<meta name="docfx:rel" content="../../">
<meta name="loc:inThisArticle" content="In this article">
<meta name="loc:searchResultsCount" content="{count} results for &quot;{query}&quot;">
<meta name="loc:searchNoResults" content="No results for &quot;{query}&quot;">
<meta name="loc:tocFilter" content="Filter by title">
<meta name="loc:nextArticle" content="Next">
<meta name="loc:prevArticle" content="Previous">
<meta name="loc:themeLight" content="Light">
<meta name="loc:themeDark" content="Dark">
<meta name="loc:themeAuto" content="Auto">
<meta name="loc:changeTheme" content="Change theme">
<meta name="loc:copy" content="Copy">
<meta name="loc:downloadPdf" content="Download PDF">
<script type="module" src="./../../public/docfx.min.js"></script>
<script>
const theme = localStorage.getItem('theme') || 'auto'
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
</script>
</head>
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="">
<header class="bg-body border-bottom">
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
<div class="container-xxl flex-nowrap">
<a class="navbar-brand" href="../../index.html">
<img id="logo" class="svg" src="../../img/HiAPI.logo.png" alt="">
</a>
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
<i class="bi bi-three-dots"></i>
</button>
<div class="collapse navbar-collapse" id="navpanel">
<div id="navbar">
<form class="search" role="search" id="search">
<i class="bi bi-search"></i>
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
</form>
</div>
</div>
</div>
</nav>
</header>
<main class="container-xxl">
<div class="toc-offcanvas">
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<nav class="toc" id="toc"></nav>
</div>
</div>
</div>
<div class="content">
<div class="actionbar">
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
<i class="bi bi-list"></i>
</button>
<nav id="breadcrumb"></nav>
</div>
<article data-uid="Anatomy-BySource-WebserviceBackend">
<h1 id="web-service-backend-source-tree">Web Service Backend Source Tree</h1>
<p>The C# half of <code>HiNC-2025-webservice</code> is an ASP.NET Core process that serves the SPA, answers its
REST calls, and pushes to it over SignalR. It is organised by the <strong>engine's domain vocabulary</strong>, not
by web-framework artifact type: a controller, its hub, its DI service and its non-web scene objects
sit together in one domain folder rather than in a <code>Controllers</code> / <code>Hubs</code> / <code>Services</code> split.</p>
<p>Folders below are ordered by how much of the shipped surface they answer for.</p>
<h2 id="reading-a-filename">Reading a Filename</h2>
<p>The role of a file is told by its suffix and base type, and the convention holds throughout:</p>
<table>
<thead>
<tr>
<th>Suffix</th>
<th>What it is</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>*Controller.cs</code></td>
<td>a REST controller with a route attribute</td>
</tr>
<tr>
<td><code>*Hub.cs</code></td>
<td>a SignalR hub — but see the two traps below</td>
</tr>
<tr>
<td><code>*Service.cs</code></td>
<td>a singleton registered in <code>Program.cs</code></td>
</tr>
<tr>
<td><code>*Displayee.cs</code></td>
<td>a scene-composition object handed to the engine; no HTTP surface at all</td>
</tr>
<tr>
<td><code>*Dtos.cs</code>, <code>*Config.cs</code></td>
<td>plain wire or settings types</td>
</tr>
</tbody>
</table>
<p>Two names deliberately break the reader's expectation. <code>Controller/ControllerController.cs</code> means
<strong>CNC controller</strong>, not an MVC controller. And <code>Mech/</code>'s <code>*DisplayController.cs</code> files are ordinary
REST controllers that attach a displayee to a rendering connection somebody else already owns — they
are not hubs.</p>
<div class="IMPORTANT">
<h5>Important</h5>
<p><strong>Folder nesting does not predict the route.</strong> <code>Mech/Topo/</code> and <code>Mech/MechBuilder/</code> expose routes
that carry no <code>api/mech/</code> prefix at all, and even inside <code>Mech/</code> two conventions coexist: the newer
ports use kebab-case paths under <code>api/mech/</code>, while the older keyed-object editors use the
controller-name default. Read the route attribute, never the path.</p>
</div>
<h2 id="composition-root">Composition Root</h2>
<p><code>Program.cs</code> is the only C# file at the repository root, and it is where the questions a reader
usually has are actually answered: which services are singletons, which hubs are mapped, and what the
middleware order is. Two facts about it are worth carrying:</p>
<ul>
<li><strong>A declared hub is not a mapped hub.</strong> <code>Program.cs</code> maps eight hub endpoints. Anything not in that
list is unreachable however complete its class looks — see the trap under <code>Execution/</code> below.</li>
<li><strong>The tree is not self-contained.</strong> The project service types <code>Program.cs</code> leans on hardest live in
the sibling HiNc engine repository, not here.</li>
</ul>
<p>Documented in <a class="xref" href="../platform/program-and-hosting.html">Program and Hosting</a>.</p>
<h2 id="execution">Execution</h2>
<p><code>Execution/</code> is the run cockpit's whole backend: playback control, the strip and cycle-line charts,
the NC-program branch index, run-output queries, and the real-time push layer.</p>
<ul>
<li><code>Execution/ExecutionController.cs</code> — the playback surface.</li>
<li><code>Execution/ExecutionChartsController.cs</code> and <code>Execution/ClStripController.cs</code> — the chart data.
Three separate classes share the case-insensitive <code>api/execution</code> prefix on purpose, one of them
routed there rather than under Mission with a comment saying why.</li>
<li><code>Execution/SessionSinkHub.cs</code> — <strong>four</strong> mapped hubs declared in one file, one per message sink, so
hub-per-file does not hold here. Each pairs with a broadcast service that <code>Program.cs</code> resolves
eagerly, so it subscribes to its sink before the first client connects.</li>
<li><code>Execution/ClStripHub.cs</code>, <code>Execution/ExecutionStatusHub.cs</code> — the strip and status pushes.</li>
</ul>
<div class="WARNING">
<h5>Warning</h5>
<p><code>Execution/ExecutionCanvasHub.cs</code> declares a hub that <code>Program.cs</code> never maps and that nothing in
the repository references. The Execution canvas rides <code>Disp/RenderingHub.cs</code> like every other
canvas. A reader looking for &ldquo;the hub behind the Execution page&rdquo; by name will find this file first
and be wrong.</p>
</div>
<p>Documented in <a class="xref" href="../execution/index.html">Execution Page</a>,
<a class="xref" href="../execution/program.html">Program Branch</a>,
<a class="xref" href="../execution/selected-step-info-panel.html">Selected-Step Info Panel</a>,
<a class="xref" href="../execution/strip-charts.html">Strip Charts</a> and <a class="xref" href="../execution/cycle-line-charts.html">Cycle-Line Charts</a>.</p>
<h2 id="mech">Mech</h2>
<p><code>Mech/</code> is the largest domain folder: the REST surfaces for the machine tool, the tool house and
cutter editing, fixtures and workpieces, spindle capability, background and coolant, and the three
runner suits. It also holds the display controllers that bind a mechanism scene onto a rendering
connection. <code>Mech/CutterDtoBuilder.cs</code> is the shared read-side DTO shape two controllers reuse, and
<code>Mech/NcSuitUsage.cs</code> is what lets the Control Tree show the CSV and CL runner branches only when the
loaded project actually plays them. No SignalR hub lives here.</p>
<ul>
<li><code>Mech/MechBuilder/</code> — the standalone mechanism-building session, held by a process-wide singleton
rather than per user. Documented in <a class="xref" href="../util/mech-builder.html">Mechanism Builder Page</a>.</li>
<li><code>Mech/Topo/</code> — one thin controller per transformer kind, each editing an instance held in the
keyed object store. Documented in
<a class="xref" href="../geom/transformer-panel.html">Transformer Select Panel</a>.</li>
<li><code>Mech/SoftNcRunnerController.cs</code> — the one endpoint family behind the Controller branch, and the
file whose snapshot decides which of that branch's nodes exist. Documented in
<a class="xref" href="../general-setup/controller/index.html">Controller Branch</a>, with
<a class="xref" href="../general-setup/controller/brand-matrix.html">Brand Matrix</a> for the snapshot flags themselves.</li>
<li><code>Mech/CsvRunnerController.cs</code> and <code>Mech/ClRunnerController.cs</code> — the two resident non-brand runner
suits, reached from tree branches the Preference menu hides by default. Documented in
<a class="xref" href="../shell/preference-menu.html">Preference Menu Dropdown</a> until those branches have a page.</li>
</ul>
<p>Documented in <a class="xref" href="../general-setup/index.html">General Setup Page</a> and
<a class="xref" href="../tool-house/index.html">Tool House Page</a> and the panels beneath them.</p>
<h2 id="missions">Missions</h2>
<p><code>Missions/</code> is the mission command tree's backend. Two things here surprise readers:</p>
<ul>
<li>The <strong>folder is plural and the route is singular</strong> — and the SPA folder is singular too.</li>
<li><code>Missions/NcOptOptionEndpoints.cs</code> is not a minimal-API endpoint file despite the name. It is a
second file of the same partial controller class, which is why its routes resolve under the mission
prefix.</li>
</ul>
<p><code>Missions/MissionCommandCatalog.cs</code> reflects over every session command carrying the catalog
attribute once per process, replacing hand-maintained kind switches, and
<code>Missions/MissionCommandFields.cs</code> does the same for annotated scalars — which is how a simple
command gets an editor without a bespoke panel. <code>Missions/ScriptCompletionService.cs</code> and
<code>Missions/ScriptCompileCheckService.cs</code> are the Roslyn pair behind the script editor; the compile
check reuses the same options and globals type the script command uses at run time.</p>
<p>Documented in <a class="xref" href="../execution/mission/mission-root-panel.html">Mission Root Panel</a> and the command panels under it.</p>
<h2 id="disp">Disp</h2>
<p><code>Disp/</code> is the rendering layer. <code>Disp/RenderingHub.cs</code> is the single transport surface for every 3D
canvas in the application — canvas initialization, pointer, key and touch input, resize, view
presets, cache clearing and snapshots — and the SPA's canvas component defaults to it, so all pages
share one hub rather than one hub per page. <code>Disp/RenderingService.cs</code> owns the per-connection
engines the hub resolves against. <code>Disp/StlPreviewController.cs</code> is the only other REST surface here.</p>
<p>The <code>*Displayee.cs</code> files are scene-graph composition objects rather than web types, and each has a
live instantiation site: the execution scene, the equipment-setup scene, the step-subtraction scene
and the two coordinate-frame displayees the first two compose in.</p>
<p>Documented in <a class="xref" href="../conventions/rendering-canvas-web-service.html">Rendering Canvas on Web Service</a>,
<a class="xref" href="../widget/renderingcanvas-tool-bar.html">RenderingCanvas Tool Bar</a> and — for
<code>Disp/StlPreviewController.cs</code> and the per-connection slot behind it —
<a class="xref" href="../util/stl-preview-pane.html">STL Preview Pane</a>.</p>
<h2 id="environments">Environments</h2>
<p><code>Environments/</code> is session and environment scope: the project lifecycle, per-user preference
persistence, the Execution page's division flags, and the shipped localized step-present catalog. It
is also where the Log Viewer's data comes from — the log endpoints sit on the project controller
beside status, new, load, save, reload, save-as and close.</p>
<p>Documented in <a class="xref" href="../shell/main-panel.html">Main Panel</a>,
<a class="xref" href="../platform/session-state.html">Session State</a>,
<a class="xref" href="../shell/preference-menu.html">Preference Menu Dropdown</a>,
<a class="xref" href="../platform/i18n.html">Internationalization</a>,
<a class="xref" href="../platform/log-viewer.html">Log Viewer Page</a> and
<a class="xref" href="../execution/step-present-dialog.html">Step Present Dialog</a>.</p>
<h2 id="common-geom-and-widget">Common, Geom and Widget</h2>
<ul>
<li><code>Common/</code> — cross-cutting infrastructure with no single domain owner: the optional login gate, the
named-root file explorer, path guards, the daily file logger, and two pieces the whole application
rests on. <code>Common/IndexService.cs</code> is the keyed object store behind the <em>index a backend object,
then edit it by key</em> pattern every geometry, transformer and widget controller uses.
<code>Common/CleanupHub.cs</code> is not a messaging hub, and it is not what bounds that store either. Its
key registry is an ordinary instance property and SignalR builds a fresh hub instance for every
invocation, so the entry <code>Add</code> records is discarded with the instance that received it and the
disconnect handler always walks an empty registry. The bound comes from the browser instead:
<code>wwwroot-src/src/composables/useCleanupHub.ts</code> posts the index-remove endpoint on
<code>Common/IndexController.cs</code> for every key it holds when its host unmounts, and again whenever a
key it registered is replaced. Documented in
<a class="xref" href="../conventions/dictionary-service-pattern.html">Dictionary Service Pattern</a>,
<a class="xref" href="../conventions/webapi-hub-cleanup-pattern.html">WebAPI Hub Cleanup Pattern</a>,
<a class="xref" href="../platform/login-and-auth.html">Login and Authentication</a> and
<a class="xref" href="../platform/log-viewer.html">Log Viewer Page</a>.</li>
<li><code>Geom/</code> — one CRUD controller per geometry kind, on the same keyed-object pattern, and nothing
else: no hubs, no services. Documented in <a class="xref" href="../geom/index.html">Geometry Panels</a>.</li>
<li><code>Widget/</code> — the generic value and lifecycle controllers the reusable inputs post to: the 3D vector,
the 4×4 matrix, and the object-management surface that handles file operations, XML editing and
copy-paste for indexed objects. Documented in
<a class="xref" href="../widget/object-management-menu-button.html">Object Management Menu Button</a>,
<a class="xref" href="../widget/vec3d-control.html">Vec3dControl Component</a> and
<a class="xref" href="../widget/mat4d-control.html">Mat4dControl Component</a>.</li>
</ul>
<h2 id="controller-and-demo">Controller and Demo</h2>
<p><code>Controller/</code> is the single-file surface behind the legacy controller page. It has a successor in
<code>Mech/SoftNcRunnerController.cs</code>, whose own doc comment says so, but <strong>both are live</strong> — the legacy
page has not been removed. Documented in <a class="xref" href="../legacy-controller.html">Legacy Controller</a>.</p>
<p><code>Demo/</code> is customer-facing sample code — a custom colour guide and a per-step optimization sweep —
compiled into the assembly with no call site in the running application. Read it as an example of
how to extend the engine, not as part of the shipped behaviour.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="index.html">Anatomy by Source Directory</a> — the other two source trees, and how this
layer is meant to be entered</li>
<li><a class="xref" href="webservice-spa.html">Web Service SPA Source Tree</a> — the front end this process
serves and answers</li>
</ul>
</article>
<div class="contribution d-print-none">
</div>
<div class="next-article d-print-none border-top" id="nextArticle"></div>
</div>
<div class="affix">
<nav id="affix"></nav>
</div>
</main>
<div class="container-xxl search-results" id="search-results"></div>
<footer class="border-top text-secondary">
<div class="container-xxl">
<div class="flex-fill">
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
</div>
</div>
</footer>
</body>
</html>