registries: make registration dynamic

Rather than having to manually hook code for registries, add a small
registration function to the registry header and use this registration
results throughout the registry interactions.

Tested:

Confirmed registries have same behavior.

```
$ curl -s -k https://localhost:18080/redfish/v1/Registries/ | jq '.Members | map(."@odata.id")'
[
  "/redfish/v1/Registries/Base",
  "/redfish/v1/Registries/HeartbeatEvent",
  "/redfish/v1/Registries/OpenBMC",
  "/redfish/v1/Registries/ResourceEvent",
  "/redfish/v1/Registries/TaskEvent",
  "/redfish/v1/Registries/Telemetry"
]
```

```
$ curl -s -k https://localhost:18080/redfish/v1/Registries/TaskEvent/TaskEvent | jq ".Messages | keys"
[
  "TaskAborted",
  "TaskCancelled",
  "TaskCompletedOK",
  "TaskCompletedWarning",
  "TaskPaused",
  "TaskProgressChanged",
  "TaskRemoved",
  "TaskResumed",
  "TaskStarted"
]
```

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: Iaa355420736a2587d9da4e995208d579443ca9b8
diff --git a/redfish-core/include/registries.hpp b/redfish-core/include/registries.hpp
index d379147..f7a8df3 100644
--- a/redfish-core/include/registries.hpp
+++ b/redfish-core/include/registries.hpp
@@ -11,6 +11,9 @@
 #include <charconv>
 #include <cstddef>
 #include <format>
+#include <functional>
+#include <map>
+#include <optional>
 #include <span>
 #include <string>
 #include <string_view>
@@ -43,6 +46,30 @@
     const char* resolution;
 };
 using MessageEntry = std::pair<const char*, const Message>;
+using MessageEntries = std::span<const MessageEntry>;
+
+struct RegistryEntry
+{
+    const Header& header;
+    const char* url;
+    MessageEntries entries;
+};
+using RegistryEntryRef = std::reference_wrapper<RegistryEntry>;
+
+auto allRegistries() -> std::map<std::string, RegistryEntry>&;
+
+auto getRegistryFromPrefix(const std::string& registryName)
+    -> std::optional<RegistryEntryRef>;
+
+auto getRegistryMessagesFromPrefix(const std::string& registryName)
+    -> MessageEntries;
+
+template <typename T>
+void registerRegistry()
+{
+    allRegistries().emplace(T::header.registryPrefix,
+                            RegistryEntry{T::header, T::url, T::registry});
+}
 
 inline std::string fillMessageArgs(
     const std::span<const std::string_view> messageArgs, std::string_view msg)
diff --git a/redfish-core/include/registries/base_message_registry.hpp b/redfish-core/include/registries/base_message_registry.hpp
index c35a7a5..e82c728 100644
--- a/redfish-core/include/registries/base_message_registry.hpp
+++ b/redfish-core/include/registries/base_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::base
+namespace redfish::registries
 {
-const Header header = {
+struct Base
+{
+static constexpr Header header = {
     "Copyright 2014-2024 DMTF. All rights reserved.",
     "#MessageRegistry.v1_6_2.MessageRegistry",
     1,
@@ -31,10 +33,11 @@
     "Base",
     "DMTF",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://redfish.dmtf.org/registries/Base.1.19.0.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "AccessDenied",
@@ -1479,4 +1482,9 @@
     undeterminedFault = 112,
     unrecognizedRequestBody = 113,
 };
-} // namespace redfish::registries::base
+}; // struct base
+
+[[gnu::constructor]] inline void registerBase()
+{ registerRegistry<Base>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries/composition_message_registry.hpp b/redfish-core/include/registries/composition_message_registry.hpp
index 26e465f..3152350 100644
--- a/redfish-core/include/registries/composition_message_registry.hpp
+++ b/redfish-core/include/registries/composition_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::composition
+namespace redfish::registries
 {
-const Header header = {
+struct Composition
+{
+static constexpr Header header = {
     "Copyright 2019-2023 DMTF. All rights reserved.",
     "#MessageRegistry.v1_6_2.MessageRegistry",
     1,
@@ -31,10 +33,11 @@
     "Composition",
     "DMTF",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://redfish.dmtf.org/registries/Composition.1.1.2.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "ConstrainedResourceAlreadyReserved",
@@ -209,4 +212,9 @@
     specifiedResourceAlreadyReserved = 11,
     unableToProcessStanzaRequest = 12,
 };
-} // namespace redfish::registries::composition
+}; // struct composition
+
+[[gnu::constructor]] inline void registerComposition()
+{ registerRegistry<Composition>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries/environmental_message_registry.hpp b/redfish-core/include/registries/environmental_message_registry.hpp
index dc3d66d..5f267cf 100644
--- a/redfish-core/include/registries/environmental_message_registry.hpp
+++ b/redfish-core/include/registries/environmental_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::environmental
+namespace redfish::registries
 {
-const Header header = {
+struct Environmental
+{
+static constexpr Header header = {
     "Copyright 2024 DMTF. All rights reserved.",
     "#MessageRegistry.v1_6_2.MessageRegistry",
     1,
@@ -31,10 +33,11 @@
     "Environmental",
     "DMTF",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://redfish.dmtf.org/registries/Environmental.1.1.0.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "FanFailed",
@@ -1280,4 +1283,9 @@
     temperatureNormal = 85,
     temperatureWarning = 86,
 };
-} // namespace redfish::registries::environmental
+}; // struct environmental
+
+[[gnu::constructor]] inline void registerEnvironmental()
+{ registerRegistry<Environmental>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries/ethernet_fabric_message_registry.hpp b/redfish-core/include/registries/ethernet_fabric_message_registry.hpp
index a19b114..04e1fb9 100644
--- a/redfish-core/include/registries/ethernet_fabric_message_registry.hpp
+++ b/redfish-core/include/registries/ethernet_fabric_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::ethernet_fabric
+namespace redfish::registries
 {
-const Header header = {
+struct EthernetFabric
+{
+static constexpr Header header = {
     "Copyright 2020-2023 DMTF. All rights reserved.",
     "#MessageRegistry.v1_6_2.MessageRegistry",
     1,
@@ -31,10 +33,11 @@
     "EthernetFabric",
     "DMTF",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://redfish.dmtf.org/registries/EthernetFabric.1.0.1.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "LLDPInterfaceDisabled",
@@ -154,4 +157,9 @@
     mLAGPeerUp = 6,
     routingFailureThresholdExceeded = 7,
 };
-} // namespace redfish::registries::ethernet_fabric
+}; // struct ethernet_fabric
+
+[[gnu::constructor]] inline void registerEthernetFabric()
+{ registerRegistry<EthernetFabric>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries/fabric_message_registry.hpp b/redfish-core/include/registries/fabric_message_registry.hpp
index 3b3c68b..295dbf0 100644
--- a/redfish-core/include/registries/fabric_message_registry.hpp
+++ b/redfish-core/include/registries/fabric_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::fabric
+namespace redfish::registries
 {
-const Header header = {
+struct Fabric
+{
+static constexpr Header header = {
     "Copyright 2014-2023 DMTF. All rights reserved.",
     "#MessageRegistry.v1_6_2.MessageRegistry",
     1,
@@ -31,10 +33,11 @@
     "Fabric",
     "DMTF",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://redfish.dmtf.org/registries/Fabric.1.0.2.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "AddressPoolCreated",
@@ -634,4 +637,9 @@
     zoneModified = 40,
     zoneRemoved = 41,
 };
-} // namespace redfish::registries::fabric
+}; // struct fabric
+
+[[gnu::constructor]] inline void registerFabric()
+{ registerRegistry<Fabric>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries/heartbeat_event_message_registry.hpp b/redfish-core/include/registries/heartbeat_event_message_registry.hpp
index d669556..b98876e 100644
--- a/redfish-core/include/registries/heartbeat_event_message_registry.hpp
+++ b/redfish-core/include/registries/heartbeat_event_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::heartbeat_event
+namespace redfish::registries
 {
-const Header header = {
+struct HeartbeatEvent
+{
+static constexpr Header header = {
     "Copyright 2021-2023 DMTF. All rights reserved.",
     "#MessageRegistry.v1_6_2.MessageRegistry",
     1,
@@ -31,10 +33,11 @@
     "HeartbeatEvent",
     "DMTF",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://redfish.dmtf.org/registries/HeartbeatEvent.1.0.1.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "RedfishServiceFunctional",
@@ -53,4 +56,9 @@
 {
     redfishServiceFunctional = 0,
 };
-} // namespace redfish::registries::heartbeat_event
+}; // struct heartbeat_event
+
+[[gnu::constructor]] inline void registerHeartbeatEvent()
+{ registerRegistry<HeartbeatEvent>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries/job_event_message_registry.hpp b/redfish-core/include/registries/job_event_message_registry.hpp
index 68eb7f3..6096398 100644
--- a/redfish-core/include/registries/job_event_message_registry.hpp
+++ b/redfish-core/include/registries/job_event_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::job_event
+namespace redfish::registries
 {
-const Header header = {
+struct JobEvent
+{
+static constexpr Header header = {
     "Copyright 2014-2023 DMTF in cooperation with the Storage Networking Industry Association (SNIA). All rights reserved.",
     "#MessageRegistry.v1_6_2.MessageRegistry",
     1,
@@ -31,10 +33,11 @@
     "JobEvent",
     "DMTF",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://redfish.dmtf.org/registries/JobEvent.1.0.1.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "JobCancelled",
@@ -147,4 +150,9 @@
     jobStarted = 6,
     jobSuspended = 7,
 };
-} // namespace redfish::registries::job_event
+}; // struct job_event
+
+[[gnu::constructor]] inline void registerJobEvent()
+{ registerRegistry<JobEvent>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries/license_message_registry.hpp b/redfish-core/include/registries/license_message_registry.hpp
index 28a2428..30bf1a2 100644
--- a/redfish-core/include/registries/license_message_registry.hpp
+++ b/redfish-core/include/registries/license_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::license
+namespace redfish::registries
 {
-const Header header = {
+struct License
+{
+static constexpr Header header = {
     "Copyright 2014-2023 DMTF. All rights reserved.",
     "#MessageRegistry.v1_6_2.MessageRegistry",
     1,
@@ -31,10 +33,11 @@
     "License",
     "DMTF",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://redfish.dmtf.org/registries/License.1.0.3.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "DaysBeforeExpiration",
@@ -142,4 +145,9 @@
     notApplicableToTarget = 6,
     targetsRequired = 7,
 };
-} // namespace redfish::registries::license
+}; // struct license
+
+[[gnu::constructor]] inline void registerLicense()
+{ registerRegistry<License>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries/log_service_message_registry.hpp b/redfish-core/include/registries/log_service_message_registry.hpp
index 700692b..6294f98 100644
--- a/redfish-core/include/registries/log_service_message_registry.hpp
+++ b/redfish-core/include/registries/log_service_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::log_service
+namespace redfish::registries
 {
-const Header header = {
+struct LogService
+{
+static constexpr Header header = {
     "Copyright 2020-2023 DMTF. All rights reserved.",
     "#MessageRegistry.v1_6_2.MessageRegistry",
     1,
@@ -31,10 +33,11 @@
     "LogService",
     "DMTF",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://redfish.dmtf.org/registries/LogService.1.0.1.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "DiagnosticDataCollected",
@@ -55,4 +58,9 @@
 {
     diagnosticDataCollected = 0,
 };
-} // namespace redfish::registries::log_service
+}; // struct log_service
+
+[[gnu::constructor]] inline void registerLogService()
+{ registerRegistry<LogService>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries/network_device_message_registry.hpp b/redfish-core/include/registries/network_device_message_registry.hpp
index 996a47f..933596e 100644
--- a/redfish-core/include/registries/network_device_message_registry.hpp
+++ b/redfish-core/include/registries/network_device_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::network_device
+namespace redfish::registries
 {
-const Header header = {
+struct NetworkDevice
+{
+static constexpr Header header = {
     "Copyright 2019-2023 DMTF. All rights reserved.",
     "#MessageRegistry.v1_6_2.MessageRegistry",
     1,
@@ -31,10 +33,11 @@
     "NetworkDevice",
     "DMTF",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://redfish.dmtf.org/registries/NetworkDevice.1.0.3.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "CableInserted",
@@ -132,4 +135,9 @@
     degradedConnectionEstablished = 4,
     linkFlapDetected = 5,
 };
-} // namespace redfish::registries::network_device
+}; // struct network_device
+
+[[gnu::constructor]] inline void registerNetworkDevice()
+{ registerRegistry<NetworkDevice>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries/openbmc_message_registry.hpp b/redfish-core/include/registries/openbmc_message_registry.hpp
index 16b5c24..0f22153 100644
--- a/redfish-core/include/registries/openbmc_message_registry.hpp
+++ b/redfish-core/include/registries/openbmc_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::openbmc
+namespace redfish::registries
 {
-const Header header = {
+struct Openbmc
+{
+static constexpr Header header = {
     "Copyright 2022 OpenBMC. All rights reserved.",
     "#MessageRegistry.v1_4_0.MessageRegistry",
     0,
@@ -31,10 +33,11 @@
     "OpenBMC",
     "OpenBMC",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://raw.githubusercontent.com/openbmc/bmcweb/refs/heads/master/redfish-core/include/registries/openbmc.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "ADDDCCorrectable",
@@ -2549,4 +2552,9 @@
     systemPowerOnFailed = 190,
     voltageRegulatorOverheated = 191,
 };
-} // namespace redfish::registries::openbmc
+}; // struct openbmc
+
+[[gnu::constructor]] inline void registerOpenbmc()
+{ registerRegistry<Openbmc>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries/platform_message_registry.hpp b/redfish-core/include/registries/platform_message_registry.hpp
index e092879..cfae35d 100644
--- a/redfish-core/include/registries/platform_message_registry.hpp
+++ b/redfish-core/include/registries/platform_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::platform
+namespace redfish::registries
 {
-const Header header = {
+struct Platform
+{
+static constexpr Header header = {
     "Copyright 2023 DMTF. All rights reserved.",
     "#MessageRegistry.v1_6_2.MessageRegistry",
     1,
@@ -31,10 +33,11 @@
     "Platform",
     "DMTF",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://redfish.dmtf.org/registries/Platform.1.0.1.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "OperatingSystemCrash",
@@ -88,4 +91,9 @@
     platformErrorAtLocation = 2,
     unhandledExceptionDetectedAfterReset = 3,
 };
-} // namespace redfish::registries::platform
+}; // struct platform
+
+[[gnu::constructor]] inline void registerPlatform()
+{ registerRegistry<Platform>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries/power_message_registry.hpp b/redfish-core/include/registries/power_message_registry.hpp
index cb5c966..13fb5a7 100644
--- a/redfish-core/include/registries/power_message_registry.hpp
+++ b/redfish-core/include/registries/power_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::power
+namespace redfish::registries
 {
-const Header header = {
+struct Power
+{
+static constexpr Header header = {
     "Copyright 2023 DMTF. All rights reserved.",
     "#MessageRegistry.v1_6_2.MessageRegistry",
     1,
@@ -31,10 +33,11 @@
     "Power",
     "DMTF",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://redfish.dmtf.org/registries/Power.1.0.1.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "BreakerFault",
@@ -1053,4 +1056,9 @@
     voltageNormal = 69,
     voltageWarning = 70,
 };
-} // namespace redfish::registries::power
+}; // struct power
+
+[[gnu::constructor]] inline void registerPower()
+{ registerRegistry<Power>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries/resource_event_message_registry.hpp b/redfish-core/include/registries/resource_event_message_registry.hpp
index 7c84971..48b8a1c 100644
--- a/redfish-core/include/registries/resource_event_message_registry.hpp
+++ b/redfish-core/include/registries/resource_event_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::resource_event
+namespace redfish::registries
 {
-const Header header = {
+struct ResourceEvent
+{
+static constexpr Header header = {
     "Copyright 2014-2023 DMTF in cooperation with the Storage Networking Industry Association (SNIA). All rights reserved.",
     "#MessageRegistry.v1_6_0.MessageRegistry",
     1,
@@ -31,10 +33,11 @@
     "ResourceEvent",
     "DMTF",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://redfish.dmtf.org/registries/ResourceEvent.1.3.0.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "AggregationSourceDiscovered",
@@ -395,4 +398,9 @@
     testMessage = 25,
     uRIForResourceChanged = 26,
 };
-} // namespace redfish::registries::resource_event
+}; // struct resource_event
+
+[[gnu::constructor]] inline void registerResourceEvent()
+{ registerRegistry<ResourceEvent>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries/sensor_event_message_registry.hpp b/redfish-core/include/registries/sensor_event_message_registry.hpp
index 3716398..fe6e301 100644
--- a/redfish-core/include/registries/sensor_event_message_registry.hpp
+++ b/redfish-core/include/registries/sensor_event_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::sensor_event
+namespace redfish::registries
 {
-const Header header = {
+struct SensorEvent
+{
+static constexpr Header header = {
     "Copyright 2022-2023 DMTF. All rights reserved.",
     "#MessageRegistry.v1_6_2.MessageRegistry",
     1,
@@ -31,10 +33,11 @@
     "SensorEvent",
     "DMTF",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://redfish.dmtf.org/registries/SensorEvent.1.0.1.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "InvalidSensorReading",
@@ -301,4 +304,9 @@
     sensorReadingNormalRange = 15,
     sensorRestored = 16,
 };
-} // namespace redfish::registries::sensor_event
+}; // struct sensor_event
+
+[[gnu::constructor]] inline void registerSensorEvent()
+{ registerRegistry<SensorEvent>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries/storage_device_message_registry.hpp b/redfish-core/include/registries/storage_device_message_registry.hpp
index 5e48038..c384470 100644
--- a/redfish-core/include/registries/storage_device_message_registry.hpp
+++ b/redfish-core/include/registries/storage_device_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::storage_device
+namespace redfish::registries
 {
-const Header header = {
+struct StorageDevice
+{
+static constexpr Header header = {
     "Copyright 2020-2023 DMTF. All rights reserved.",
     "#MessageRegistry.v1_6_2.MessageRegistry",
     1,
@@ -31,10 +33,11 @@
     "StorageDevice",
     "DMTF",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://redfish.dmtf.org/registries/StorageDevice.1.2.1.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "BatteryCharging",
@@ -493,4 +496,9 @@
     writeCacheProtected = 32,
     writeCacheTemporarilyDegraded = 33,
 };
-} // namespace redfish::registries::storage_device
+}; // struct storage_device
+
+[[gnu::constructor]] inline void registerStorageDevice()
+{ registerRegistry<StorageDevice>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries/task_event_message_registry.hpp b/redfish-core/include/registries/task_event_message_registry.hpp
index 08e9014..137f181 100644
--- a/redfish-core/include/registries/task_event_message_registry.hpp
+++ b/redfish-core/include/registries/task_event_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::task_event
+namespace redfish::registries
 {
-const Header header = {
+struct TaskEvent
+{
+static constexpr Header header = {
     "Copyright 2014-2020 DMTF in cooperation with the Storage Networking Industry Association (SNIA). All rights reserved.",
     "#MessageRegistry.v1_4_1.MessageRegistry",
     1,
@@ -31,10 +33,11 @@
     "TaskEvent",
     "DMTF",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://redfish.dmtf.org/registries/TaskEvent.1.0.3.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "TaskAborted",
@@ -160,4 +163,9 @@
     taskResumed = 7,
     taskStarted = 8,
 };
-} // namespace redfish::registries::task_event
+}; // struct task_event
+
+[[gnu::constructor]] inline void registerTaskEvent()
+{ registerRegistry<TaskEvent>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries/telemetry_message_registry.hpp b/redfish-core/include/registries/telemetry_message_registry.hpp
index ed59bf6..abb2874 100644
--- a/redfish-core/include/registries/telemetry_message_registry.hpp
+++ b/redfish-core/include/registries/telemetry_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::telemetry
+namespace redfish::registries
 {
-const Header header = {
+struct Telemetry
+{
+static constexpr Header header = {
     "Copyright 2023 DMTF. All rights reserved.",
     "#MessageRegistry.v1_6_2.MessageRegistry",
     1,
@@ -31,10 +33,11 @@
     "Telemetry",
     "DMTF",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://redfish.dmtf.org/registries/Telemetry.1.0.0.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "TriggerDiscreteConditionMet",
@@ -168,4 +171,9 @@
     triggerNumericBelowUpperCritical = 6,
     triggerNumericReadingNormal = 7,
 };
-} // namespace redfish::registries::telemetry
+}; // struct telemetry
+
+[[gnu::constructor]] inline void registerTelemetry()
+{ registerRegistry<Telemetry>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries/update_message_registry.hpp b/redfish-core/include/registries/update_message_registry.hpp
index 0c5d1f6..578b77a 100644
--- a/redfish-core/include/registries/update_message_registry.hpp
+++ b/redfish-core/include/registries/update_message_registry.hpp
@@ -17,9 +17,11 @@
 
 // clang-format off
 
-namespace redfish::registries::update
+namespace redfish::registries
 {
-const Header header = {
+struct Update
+{
+static constexpr Header header = {
     "Copyright 2014-2023 DMTF. All rights reserved.",
     "#MessageRegistry.v1_6_2.MessageRegistry",
     1,
@@ -31,10 +33,11 @@
     "Update",
     "DMTF",
 };
-constexpr const char* url =
+
+static constexpr const char* url =
     "https://redfish.dmtf.org/registries/Update.1.0.2.json";
 
-constexpr std::array registry =
+static constexpr std::array registry =
 {
     MessageEntry{
         "ActivateFailed",
@@ -245,4 +248,9 @@
     verificationFailed = 13,
     verifyingAtComponent = 14,
 };
-} // namespace redfish::registries::update
+}; // struct update
+
+[[gnu::constructor]] inline void registerUpdate()
+{ registerRegistry<Update>(); }
+
+} // namespace redfish::registries
diff --git a/redfish-core/include/registries_selector.hpp b/redfish-core/include/registries_selector.hpp
index 01160b7..6440ca5 100644
--- a/redfish-core/include/registries_selector.hpp
+++ b/redfish-core/include/registries_selector.hpp
@@ -1,83 +1,17 @@
 // SPDX-License-Identifier: Apache-2.0
 // SPDX-FileCopyrightText: Copyright OpenBMC Authors
 #pragma once
+// NOLINTNEXTLINE(misc-include-cleaner)
 #include "registries.hpp"
+// NOLINTNEXTLINE(misc-include-cleaner)
 #include "registries/base_message_registry.hpp"
+// NOLINTNEXTLINE(misc-include-cleaner)
 #include "registries/heartbeat_event_message_registry.hpp"
+// NOLINTNEXTLINE(misc-include-cleaner)
 #include "registries/openbmc_message_registry.hpp"
+// NOLINTNEXTLINE(misc-include-cleaner)
 #include "registries/resource_event_message_registry.hpp"
+// NOLINTNEXTLINE(misc-include-cleaner)
 #include "registries/task_event_message_registry.hpp"
+// NOLINTNEXTLINE(misc-include-cleaner)
 #include "registries/telemetry_message_registry.hpp"
-
-#include <optional>
-#include <span>
-#include <string_view>
-
-namespace redfish::registries
-{
-struct HeaderAndUrl
-{
-    const Header& header;
-    const char* url;
-};
-
-inline std::optional<registries::HeaderAndUrl>
-    getRegistryHeaderAndUrlFromPrefix(std::string_view registryName)
-{
-    if (base::header.registryPrefix == registryName)
-    {
-        return HeaderAndUrl{base::header, base::url};
-    }
-    if (heartbeat_event::header.registryPrefix == registryName)
-    {
-        return HeaderAndUrl{heartbeat_event::header, heartbeat_event::url};
-    }
-    if (openbmc::header.registryPrefix == registryName)
-    {
-        return HeaderAndUrl{openbmc::header, openbmc::url};
-    }
-    if (resource_event::header.registryPrefix == registryName)
-    {
-        return HeaderAndUrl{resource_event::header, resource_event::url};
-    }
-    if (task_event::header.registryPrefix == registryName)
-    {
-        return HeaderAndUrl{task_event::header, task_event::url};
-    }
-    if (telemetry::header.registryPrefix == registryName)
-    {
-        return HeaderAndUrl{telemetry::header, telemetry::url};
-    }
-    return std::nullopt;
-}
-
-inline std::span<const MessageEntry> getRegistryFromPrefix(
-    std::string_view registryName)
-{
-    if (base::header.registryPrefix == registryName)
-    {
-        return {base::registry};
-    }
-    if (heartbeat_event::header.registryPrefix == registryName)
-    {
-        return {heartbeat_event::registry};
-    }
-    if (openbmc::header.registryPrefix == registryName)
-    {
-        return {openbmc::registry};
-    }
-    if (resource_event::header.registryPrefix == registryName)
-    {
-        return {resource_event::registry};
-    }
-    if (task_event::header.registryPrefix == registryName)
-    {
-        return {task_event::registry};
-    }
-    if (telemetry::header.registryPrefix == registryName)
-    {
-        return {telemetry::registry};
-    }
-    return {openbmc::registry};
-}
-} // namespace redfish::registries