HyperCore uses many modern technologies (relative to its ancestor systems). Being built largely around Microsoft .NET (CORE, via C#) and SQL Server, many of the concepts and examples are within that stack.
Since HyperCore is an evolution and co-operational partner of a previous codebase employed to generate solutions in its organization, it is useful to understand the historical code-base of its ancestor systems. These included .NET Framework code and client-server style SQL Server (heavy on the use of stored procedures); with SQL Server being the logic processing server to device-integration service-code, WPF and Windows CE front-ends .
Dependency Injection
HyperCore relies on dependency injection for discovery, configuration and customization of its service-code. For developers who haven’t worked with dependency injection or inversion of control, this can be one of the larger barriers to understand the processing systems built with HyperCore.
Task-Friendly Async Code
Since HyperCore sits on a more modern stack than it’s ancestors, awareness of asynchronous code and its differences from simple thread management needs to be accounted for. Concurrency checks and primitives HyperCore use avoid thread-bound monitors and are based on task-friendly mechanisms such as semaphores that are not owned by threads and cannot be orphaned by sudden shifts when the underlying task framework’s async model shifts between threads.
Other thread-safe primitives such as concurrent collections are still used, but care must be taken by implementers to avoid complex thread control issues within generator code for methods such as GetOrAdd and AddOrUpdate.
Strongly-Typed Keys
Data models using strongly-typed keys, as I document and demonstrate in one of my GitHub repos.
Parametric Polymorphism: Generics, Virtual Methods and Abstractions
Data model classes that support customized field additions are serviced by kernel code that accept generic-type arguments constrained to the base types. These servicing classes define overridable virtual functions allowing the customized fields to be updated, and defaulted within the context of the kernel-code.
A number of kernel services provide default implementations that accept generic parameters, simplifying construction and use of selected patterned-based code functions. Examples of such functions include lookup caching and concurrency control.
Interface/Implementation Separation
Clean use of dependency injection tends to encourage a natural separation of interface from processing logic. HyperCore follows this guidance generally. Beyond specific interfaces and classes, the classification of entire packages and assemblies are often considered as fulfilling some part in this separation of model, interface or implementation. This holds as guidance for both kernel functionality and customer implementations.
Interface-only packages and assemblies can be used in proxy classes and remote client code, simplifying the creation of apps in UI frameworks (such as MAUI for mobile and desktop, and Blazor-based mobile web interfaces, hybrid desktop and full browser) as these frameworks and runtimes can consume .NET packages and assemblies.
Additionally, this separation discourages integration and implementation coders from touching intralogistical kernel objects directly, increasing the stability of the system as a whole.
Transaction Control
HyperCore relies on transactional relational database operations. Ensuring consistency across multiple intralogistical systems and base-kernel systems is paramount for operational integrity, audit trails, problem solving and proper bookkeeping.
The typical HyperCore interaction that alters data uses an ICommitter to commit one or more ICommittables in a single transaction scope. ICommittables themselves can chain to other ICommittable instances or perform an action that is transactionally bound (typically involving a database connection). Chained committables are tracked in the committer to avoid duplicate commits from multiple services.
If the transaction processing commits without error, then all the ICommittables are informed they can accept their changes, which is when they can clear change tracking or pending DB commands, in case the context may be reused for more changes and commits.
Transaction control for the built-in logging implementation happens outside of user controlled commits, and is ensured to occur by use of ASPNET pipeline components that write the log entries if the logging is still active, by similar wrappers in recurring agent scope processing, and in batch operations. It is possible to force or explicitly write log entries prior to interaction, job or batch complete; writing entries clears them from the log buffer graph so they will not duplicate if flushed this way.
OAuth2/OpenID Connect
HyperCore supports token-based authorization using OpenID Connect and OAuth2. Using Automate Identify Services (AIS) is the simplest mechanism to accomplish this as the mapping of clients, scopes and resources is fully supported in the system model of the kernel, and AIS can use password credentials from its user store to authenticate users and generate tokens, or can forward authentication to a customer hosted authentication source.
While possible to configure the direct use of a customer hosted authorization token source, the configuration of HyperCore itself and the authorization source involves more project work to ensure agreement on scopes, clients and resources.
It is also possible to use AIS as an authorization source for customer scopes, clients and resources.
Memory Cached Lookups
Slowly changing (i.e., largely static) data used for “types”, processing states and rules are kept in memory lookup caches that can be signaled to refresh during the seldom performed updates of their data. Default implementations rely on generic abstraction and dependency injection defined in the base-kernel, as are available by referencing the appropriate lookup key and value (if defined) in the service constructor.