Lockjaw.Core
2.0.2.58
See the version list below for details.
dotnet add package Lockjaw.Core --version 2.0.2.58
NuGet\Install-Package Lockjaw.Core -Version 2.0.2.58
<PackageReference Include="Lockjaw.Core" Version="2.0.2.58" />
<PackageVersion Include="Lockjaw.Core" Version="2.0.2.58" />
<PackageReference Include="Lockjaw.Core" />
paket add Lockjaw.Core --version 2.0.2.58
#r "nuget: Lockjaw.Core, 2.0.2.58"
#:package Lockjaw.Core@2.0.2.58
#addin nuget:?package=Lockjaw.Core&version=2.0.2.58
#tool nuget:?package=Lockjaw.Core&version=2.0.2.58
Lockjaw.Core
The shared model behind Lockjaw: it reads environment-prefixed settings from app.config and
appsettings.json, resolves each key to the environment you have selected, and defines the snapshot
the Lockjaw app publishes and clients read.
Most applications want Lockjaw.Client, not this package. Reference Lockjaw.Core directly only when you are hosting the resolution yourself or building tooling on top of Lockjaw.
netstandard2.0, with no UI dependency.
What it does
Keys are prefixed with the environment they belong to. Lockjaw groups the prefixed keys into one logical setting holding every environment's value:
<add key="Development_ApiUrl" value="https://localhost:5001/api" />
<add key="Production_ApiUrl" value="https://api.contoso.com/v2" />
becomes a single ApiUrl entry that resolves to whichever environment is selected.
Hosting it yourself
using var host = new LockjawHost(new LockjawOptions
{
InstanceName = "default",
Environments =
{
new EnvironmentDefinition("Local", "Local_"),
new EnvironmentDefinition("Test", "Test_", "#7C3AED")
},
DefaultEnvironment = "Development"
}).Initialize();
var apiUrl = host.Catalog.Get("ApiUrl");
host.Catalog.SelectAll("Test");
Initialize() reads the configuration, layers on any saved edits, restores the remembered
selections, and publishes a snapshot. Every later change republishes automatically.
Reload() re-reads the configuration files and rebuilds the catalog, keeping the user's edits and
chosen environments — use it when a file has changed on disk. The sources are read in full before
anything is discarded, so a file that has become unreadable throws and leaves the previous state
exactly as it was.
The host also watches those files and raises ConfigurationChanged once they settle — debounced,
because editors write a file in several steps. It reports rather than reloads, so the owner picks the
moment; a UI reloads on its own thread, where rebuilding what is on screen is safe:
host.ConfigurationChanged += (s, e) => dispatcher.BeginInvoke(new Action(() => host.Reload()));
Turn it off with LockjawOptions.WatchConfigurationFiles, or change the settle time with
WatchQuietPeriodMs.
Key types
| Type | Purpose |
|---|---|
LockjawHost |
Loads configuration, persists edits and choices, publishes the snapshot |
LockjawOptions |
Environments, prefixes, default environment, file locations, sources |
SettingsCatalog |
The merged, prefix-stripped settings; selection and full editing API |
SettingEntry |
One key with every environment's value, and the one in use |
EnvironmentDefinition |
An environment: name, key prefix, optional color |
ResolvedSnapshot / ResolvedSetting |
The published format clients read |
SettingsTransfer / SettingsBundle |
Import and export |
LocalConfigLoader |
Reads the current process's own config into a catalog |
IConfigurationSource / InMemoryConfigSource |
Feed Lockjaw values from anywhere |
Colon-delimited paths
JsonConfigSource flattens nested objects and arrays into colon paths, as .NET configuration does —
{ "Logging": { "Level": "Debug" } } becomes Logging:Level, and array items take their index.
SettingsCatalog will strip an environment prefix from any segment of such a path, so either the
whole subtree or a single leaf can carry it.
Environments are open-ended
Development_ and Production_ are only the defaults. Declare whatever you use — Local_,
Test_, Staging_ — and Lockjaw picks those keys up. The longest matching prefix wins, so Test_ and
Test_Local_ can coexist. A key with no value in the default environment falls back to the first
declared environment it does have.
Editing
The catalog is editable, and edits never rewrite your configuration files — they are held as a diff and persisted separately, so config keeps its comments and every value can be reverted:
using (catalog.BeginEdit()) // one change notification for the batch
{
catalog.SetValue("ApiUrl", SettingKind.AppSetting, "Local", "http://localhost:5000");
catalog.SetValue("ApiUrl", SettingKind.AppSetting, "Test", "https://test.contoso.com");
}
catalog.IsOverridden("ApiUrl", SettingKind.AppSetting, "Local"); // differs from config?
catalog.ConfigValue("ApiUrl", SettingKind.AppSetting, "Local"); // what config actually says
catalog.RevertValue("ApiUrl", SettingKind.AppSetting, "Local"); // put it back
Import and export
var bundle = SettingsTransfer.Export(catalog, "default", DateTime.UtcNow);
SettingsTransfer.Write(bundle, path);
var result = SettingsTransfer.Import(catalog, SettingsTransfer.Read(path),
new ImportOptions { Mode = ImportMode.Merge });
Values naming an environment the target does not declare are skipped and reported rather than creating settings nothing can display.
Notes
- Persistence is best effort: a locked or corrupt store costs the saved choices, never the host app.
- A malformed configuration section makes .NET throw while parsing it; local-config reads treat that as "no values" rather than crashing.
LockjawHostisIDisposable— disposing saves edits and selections.
See also
- Lockjaw.Client — what applications reference to read the resolved values.
- The Lockjaw app — the tray UI over this model.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 is compatible. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.6.1
- Sipc (>= 0.3.0)
- System.Configuration.ConfigurationManager (>= 8.0.1)
- System.Text.Json (>= 8.0.5)
-
.NETStandard 2.0
- Sipc (>= 0.3.0)
- System.Configuration.ConfigurationManager (>= 8.0.1)
- System.Text.Json (>= 8.0.5)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Lockjaw.Core:
| Package | Downloads |
|---|---|
|
Lockjaw.Client
Read the environment currently selected in the Lockjaw app from any .NET application, and react the moment it changes. Lockjaw keeps every environment's values in one configuration — keys prefixed Development_, Production_, or whatever else you declare — and lets you choose, per setting and while your app is running, which one each resolves to. Ask for the key without its prefix and you get the selected value; no configuration needed on your side. Values update live, stay readable when the Lockjaw app is not running, and fall back to the consuming application's own app.config or appsettings.json when nothing has been published. Includes a UI-thread marshalling helper for WPF and WinForms. |
GitHub repositories
This package is not used by any popular GitHub repositories.
2.2.0
- The snapshot push now travels over SIPC, a semaphore-only peer mesh, instead of a named pipe. LockjawHost joins the instance's mesh and publishes each republished snapshot to a channel its clients subscribe to. No sockets, pipes or shared files are used, so live updates keep working where those are locked down. The snapshot file is still written; the push is added on top. Controlled by LockjawOptions.BroadcastChanges (on by default).
- Requires SIPC 0.3.0+, whose channels are strongly consistent: once a client has subscribed, every later publish is guaranteed to reach it, so a selection change never silently stops reaching a client. Per-word send timeouts are bounded so a client killed without disposing (a debugger stop) cannot stall delivery to the others.
- LockjawHost.Suspend()/Resume() clear and restore publishing, so a host can behave as if no app is present and its clients fall back to their own configuration.
- LockjawOptions.AllowCrossAccountClients now places the mesh's semaphores in the global namespace so a client in another session or under a different Windows account can join (off by default); that namespace may require privilege and the client must opt in to match it. Same-user clients on the same desktop work without it.
2.1.0
- LockjawHost now pushes each republished snapshot to connected clients over a named pipe, so a selection change reaches them at once instead of relying on them noticing the snapshot file change — which a locked-down machine can silently prevent. The snapshot file is still written; the push is added on top. Controlled by LockjawOptions.BroadcastChanges (on by default).
- LockjawOptions.AllowCrossAccountClients widens the pipe's ACL so a client under a different Windows account can receive pushes (off by default). Same-user clients, including in another logon session, work without it.
2.0.2
- Environments are open-ended and declared by name + prefix, replacing the fixed Development/Production enum.
- Full editing API on SettingsCatalog: set, clear, rename, delete, revert, with batched change notification.
- Edits persist as a diff against the configuration files, so config is never rewritten and any value can be reverted.
- Import and export via SettingsTransfer, with merge and replace modes.
- The published snapshot now carries the environment list, including colors and the default.