Nuplane 0.0.8
dotnet add package Nuplane --version 0.0.8
NuGet\Install-Package Nuplane -Version 0.0.8
<PackageReference Include="Nuplane" Version="0.0.8" />
<PackageVersion Include="Nuplane" Version="0.0.8" />
<PackageReference Include="Nuplane" />
paket add Nuplane --version 0.0.8
#r "nuget: Nuplane, 0.0.8"
#:package Nuplane@0.0.8
#addin nuget:?package=Nuplane&version=0.0.8
#tool nuget:?package=Nuplane&version=0.0.8
Nuplane
Nuplane is a runtime control plane for NuGet packages. It lets your .NET application install, update, and load NuGet packages while it is running — no restart required.
Drop a .nupkg into a watched folder or point Nuplane at a NuGet feed. It resolves the package, extracts it to a deterministic local store, loads the assemblies into an isolated context, and signals your host. Your host decides what to do with the loaded types.
What you can build
The most immediate use case is dynamic NuGet package installation into a live .NET application:
- Hot-reload plugin systems — ship plugins as NuGet packages; drop them into a local feed folder at runtime and have them discoverable in the live app within seconds.
- Modular feature delivery — split an application into independently versioned feature packages and update individual features at runtime without a full redeployment.
- SaaS per-tenant extensions — load per-tenant behaviour packages at runtime; each tenant gets their customizations without shared hosting risk.
- Workflow and rule engines — deploy new steps, validators, or rules as packages and pick them up live without restarting the engine.
- Internal tool hosts — extend internal platforms dynamically by pushing a new package to a watched folder; the host picks it up automatically.
See the End-to-End ASP.NET Plugin Demo below for a full walkthrough of the drop-folder workflow with a live ASP.NET Core host.
Nuplane handles the infrastructure: feed resolution, deterministic storage, transactional updates, last-known-good fallback, isolated assembly loading, and structured change events. Your host decides what the loaded packages mean.
📖 Start With The Wiki
If you are evaluating or onboarding to Nuplane, start with the repository-owned wiki under docs/wiki/:
Home— product framing and audience routesOverview— why Nuplane exists, what it does, and what it does not doGetting Started— recommended first-use pathUsage Guide— core-runtime vs optional-loading usage guidanceArchitecture Guide— module map and repository-to-concept viewConcepts and Glossary— normalized terminology
The wiki follows a hybrid-hub model: it is self-sufficient for evaluation and onboarding, while deeper validation details, roadmap history, sample mechanics, and other fast-moving reference material remain repository-owned.
✨ What Nuplane Does
- Resolve packages from NuGet v3 feeds
- Support
.nupkglocal directory feed deployment - Maintain a deterministic on-disk package store
- Reconcile desired vs actual package state
- Apply atomic per-package updates
- Provide last-known-good (LKG) fallback
- Emit structured change events for host integration
- Offer integrity validation hooks
- Provide operational visibility (logs, metrics, health)
🚫 What Nuplane Does Not Do
- It does not define a plugin entrypoint model.
- It does not mutate your DI container.
- It does not impose activation semantics.
- It does not guarantee in-process assembly unload.
- It does not sandbox untrusted code.
Nuplane is infrastructure. Your host decides what to do when packages change.
🧠 Core Concept
Nuplane implements a simple control loop:
- Determine desired packages
- Compare with current state
- Compute a diff
- Apply transactional updates
- Emit change events
Hosts (e.g., web apps, workers, modular systems) react to change events by reloading, rescanning, or reconfiguring as needed.
📚 Terminology and Concepts
Desired state
The set of packages Nuplane should make active. Desired state comes from configured sources, such as remote feeds, directory-backed feeds, or other desired-state providers.
Actual state
The packages currently installed and active in the local package store. Nuplane compares actual state with desired state during each reconciliation cycle.
Feed
A named package source Nuplane can resolve from.
A feed can point at a NuGet v3 service index or at a local directory containing .nupkg files.
Feeds can also define trust level, credentials, and include patterns.
Include pattern
A package ID filter applied to a feed.
For example, MyApp.Plugins.* means that feed is authoritative for matching package IDs only.
These patterns also inform source/package trust defaults unless you explicitly override trust options.
Directory-backed feed
A local folder treated as a feed.
Nuplane can scan it for .nupkg files and optionally watch it for file changes with debounce.
This is what powers the sample's drop-folder workflow.
Reconciliation
A control-loop cycle where Nuplane:
- reads desired state
- resolves package versions from feeds
- computes the diff versus actual state
- applies transactional add/update/remove operations
- emits observer events and operational telemetry
Reconciliation can be manual, startup-triggered, or periodic.
Package store
Nuplane's deterministic on-disk storage area for downloaded packages, current-package pointers, staging work, and persisted state. It is designed so updates are atomic and safe to retry.
Active version
The version Nuplane currently considers live for a package in the local store. This is the version your host should treat as the current runtime target.
Last-known-good (LKG)
The most recent version Nuplane successfully applied for a package. If a future update fails, Nuplane can preserve the LKG state rather than leaving the system half-updated.
Observer
A host-owned callback type registered in DI. Nuplane emits events such as package-change completion or package-loading completion, and your observers decide what the application should do in response.
Optional loading
An opt-in subsystem that loads resolved packages into assembly load contexts. Nuplane supports two package load modes:
Collectibleis the default mode for isolated or scan-only plugin scenarios where package assemblies should remain unloadable when references drain.HostIntegratedis for packages that contribute application-lifetime framework types such as DI registrations, endpoints, hosted services, options, validators, or database migrations.
Shared assemblies remain a separate policy: they solve contract/type identity by resolving selected abstractions from the host/default context, but they do not by themselves make package assemblies framework-integrated or resolvable by name. Nuplane can manage shared contract assemblies, deactivation timeout, unload coordination for collectible packages, and host-integrated assembly-name resolution, but your host still decides what loaded types mean.
Module registration
Each optional Nuplane module (loading, directory-source) provides its own direct IServiceCollection registration extension.
You can register modules independently of the builder surface, or use the module-owned builder integration package for fluent configuration.
If the same module is registered through both paths, the last registration wins and the service graph remains deduplicated.
Configuration-driven setup
A way to declare Nuplane infrastructure in configuration instead of code.
Nuplane:Setup covers builder-only concepts like feeds, polling, and state-file persistence, while Nuplane:Loading covers optional runtime loading behavior.
Observer registration and other host-specific reactions stay in code.
📦 Quick Start
Use the Nuplane configuration section for infrastructure, then keep host-owned reactions in code:
using Nuplane;
using Nuplane.Loading.Hosting.Builder;
using Nuplane.Sources.Directory.Hosting.Builder;
using Nuplane.Sources.Directory.Hosting.Configuration;
var builder = WebApplication.CreateBuilder(args);
var nuplaneConfiguration = builder.Configuration.GetSection("Nuplane");
builder.Services.AddNuplane(nuplaneConfiguration, nuplane =>
{
nuplane.AddDirectoryFeedsFromConfiguration(nuplaneConfiguration);
nuplane.AutoloadPackages(nuplaneConfiguration.GetSection("Loading"));
nuplane.OnPackagesChanged<PackageChangeObserver>();
nuplane.OnPackagesLoaded<PluginDiscoveryObserver>();
});
{
"Nuplane": {
"Setup": {
"AutomaticReconciliation": true,
"PollInterval": "00:01:00",
"Feeds": [
{
"Name": "local-packages",
"DirectoryPath": "packages",
"IncludePatterns": [
"*"
],
"Directory": {
"Watch": true,
"DebounceWindow": "00:00:01"
}
},
{
"Name": "nuget.org",
"ServiceIndex": "https://api.nuget.org/v3/index.json",
"IncludePatterns": [
"Elsa.*"
]
}
]
},
"Loading": {
"Enabled": true,
"DefaultLoadMode": "Collectible",
"PackageLoadModes": [
{
"PackageId": "Elsa.Persistence.EFCore.PostgreSql",
"LoadMode": "HostIntegrated"
}
],
"SharedAssemblies": [
{
"Name": "Nuplane.Abstractions",
"PublicKeyToken": "31bf3856ad364e35",
"MajorVersion": 1
}
]
}
}
}
When packages are added, updated, or removed, Nuplane emits PackageChangeSet events for your host to react to.
Query-first catalog access
Observers are supplemental invalidation and logging signals. For authoritative reads, query the standalone catalog services directly:
using Nuplane.Sample.AspNetCore.Catalog;
app.MapSampleCatalog();
- Use
IActivePackageCatalog.GetActivePackagesAsync(ct)when you only need the authoritative active package inventory. - Use
IPackageLoadStateCatalog.GetLoadStateAsync(ct)when the optional loading module is installed and you need current-process load-state availability or per-package load status. - Use
IPackageAssemblyCatalogas the default loading-enabled host integration surface when you want sane-default access to loadedAssemblyinstances for the current active package set without manually filtering load-state snapshots first. - Use
IPackageAssemblyCatalog.GetAssembliesAsync(packageId, ct)when you want the currently active loaded version for one package identifier. - Use
IPackageTypeFinder.FindTypesAsync(packageId, ct)only as an optional convenience after assembly access when you want Nuplane to apply assignability-based filtering over the current active loaded version for one package. - Use a host-owned query service such as the sample
PluginCatalogwhen you want to explicitly discover allIPluginimplementations from the current active loaded package set while keeping package-aware control over the discovery flow. - In the sample HTTP payloads for
/catalog/assembliesand/catalog/assemblies/{packageId},loadedAssembliesis the runtime-loaded assembly view whileselectedAssemblyReferencesis the durable loader-selected metadata view. - Use the admin API (
/nuplane/admin/packages,/nuplane/admin/load-state,/nuplane/admin/state) when you want HTTP access to the same composed read surfaces.
Clean-break notes for query surfaces
GET /nuplane/admin/load-stateis owned byNuplane.Loading.Api, not by the core admin packages.GET /nuplane/admin/snapshotis intentionally removed; package inventory and operational state are now separate reads.- The sample's
/catalog/packages,/catalog/load-state,/catalog/assemblies, and/catalog/pluginsendpoints intentionally teach the default host decision tree in that order: active packages, load state, assemblies, then optional type finding. - The sample observers demonstrate cache invalidation and logging only; they are not the authoritative package/loading inventory source.
- These surface changes are intentional breaking changes for hosts that previously depended on merged snapshot or core-admin loading compatibility payloads.
Configuration model
Nuplane has two configuration layers:
Nuplane:Setup— the builder-only setup surface:- automatic reconciliation
- poll interval
- optional state file path
- feeds, include patterns, directory watcher settings
- existing runtime option sections under
Nuplane:*— advanced operator configuration:ReconciliationFeedResolutionSourceTrustFeedTrustPolicyLockFileCleanupPolicyConvergenceTrustedSourcePolicyStoreRegistry
Nuplane:Loading— optional loading settings:EnabledDeactivationTimeoutActiveStoreRootDefaultLoadModePackageLoadModesSharedAssemblies
For unrestricted feeds, prefer one of these explicit forms:
- configuration:
"IncludePatterns": ["*"] - configuration alias:
"IncludeAll": true - fluent API:
feed.IncludeAll()
Kubernetes And Restart Persistence
Nuplane keeps runtime state and extracted packages on disk. If a pod restarts with an empty filesystem, Nuplane will need to reconcile and acquire packages again.
To avoid that, persist both of these paths on a mounted volume:
- the package install root
- the store state file
Recommended approach:
- use one persistent volume per replica
- mount it at a stable path such as
/var/lib/nuplane - configure package extraction under
/var/lib/nuplane/packages - configure store state at
/var/lib/nuplane/store-state.json
Example configuration:
{
"Nuplane": {
"Setup": {
"StateFilePath": "/var/lib/nuplane/store-state.json",
"AutomaticReconciliation": true,
"PollInterval": "00:01:00",
"Feeds": [
{
"Name": "nuget.org",
"ServiceIndex": "https://api.nuget.org/v3/index.json",
"IncludePatterns": [
"*"
]
}
]
},
"FeedResolution": {
"PackageInstallRoot": "/var/lib/nuplane/packages"
}
}
}
Operational guidance:
- prefer a per-replica persistent volume, not a single shared read-write-many package store across replicas
- for Kubernetes, a
StatefulSetwith one volume per replica is the best fit when warm restarts matter - if
UseInMemoryStore=trueis enabled, restart persistence is intentionally disabled - if
PackageInstallRootis not persisted, Nuplane may need to download and extract packages again after pod restart even if the store state file is preserved
With both paths persisted, a restarted pod can typically reload prior active state and reuse previously extracted packages instead of rebuilding its local package store from scratch.
Example StatefulSet sketch:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nuplane-host
spec:
serviceName: nuplane-host
replicas: 2
selector:
matchLabels:
app: nuplane-host
template:
metadata:
labels:
app: nuplane-host
spec:
containers:
- name: app
image: your-registry/nuplane-host:latest
volumeMounts:
- name: nuplane-data
mountPath: /var/lib/nuplane
env:
- name: Nuplane__Setup__StateFilePath
value: /var/lib/nuplane/store-state.json
- name: Nuplane__FeedResolution__PackageInstallRoot
value: /var/lib/nuplane/packages
volumeClaimTemplates:
- metadata:
name: nuplane-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
This keeps each replica's package cache and persisted state warm across pod restarts while avoiding a shared multi-writer package store.
Storage planning notes:
- size the PVC for more than just the currently active package set; leave headroom for staged downloads, retained previous versions, and transient extraction work
- Nuplane may keep prior package versions on disk to preserve transactional safety and last-known-good behavior
- if you enable cleanup policies, align retention settings with your rollback expectations and available disk budget
- if you do not enable cleanup, expect disk usage to grow over time as new package versions are acquired
Breaking change: omitted include filters no longer mean “accept everything.” A feed without
IncludePatterns,IncludeAll, orfeed.IncludeAll()now contributes no packages.
Configuration vs code
Use configuration for infrastructure and policy:
- feeds
- polling and persistence
- loading options
- trust and resolution settings
Keep application-specific behavior in code:
OnPackagesChanged<T>()OnPackagesLoaded<T>()- any logic that decides how your host reacts to package changes
Fluent builder still works
If you prefer code-first setup, the fluent API remains available:
builder.Services.AddNuplane(nuplane =>
{
nuplane.PollEvery(TimeSpan.FromSeconds(60));
nuplane.AddDirectoryFeed("local-packages", "packages", dir =>
{
dir.Watch = true;
dir.DebounceWindow = TimeSpan.FromSeconds(1);
dir.IncludeAll();
});
});
🗂 Package Store Layout
Nuplane maintains a deterministic store:
root/
state.json
packages/{id}/{version}/
current/{id} -> ../packages/{id}/{version}
staging/
Updates are atomic:
- Download to staging
- Validate
- Move to immutable store
- Atomically switch active version
- Persist state
If anything fails, the previous version remains active.
🔄 Reconciliation Model
Nuplane runs a polling loop (configurable interval):
- Aggregate desired state (explicit + discovery sources)
- Resolve versions from feeds
- Compute diff (add / update / remove)
- Apply per-package transactions
- Emit change events
The process is idempotent and safe to retry.
🔍 Desired State Sources
Nuplane can discover desired packages from configured feeds and sources.
Directory-backed local feed
builder.Services.AddNuplane(nuplane =>
{
nuplane.AddDirectoryFeed("local-packages", "packages", dir =>
{
dir.Watch = true;
dir.DebounceWindow = TimeSpan.FromSeconds(1);
dir.Include("MyApp.Plugins.*");
});
});
Dropping a .nupkg into the folder adds it.
Removing the file removes it.
The same setup can be declared through Nuplane:Setup:Feeds when you prefer configuration-driven hosts.
🧪 End-to-End ASP.NET Plugin Demo — Dynamic Package Installation in Action
The sample app shows what it looks like to install a NuGet package into a running ASP.NET Core application without restarting it:
- A local
packagesfolder acts as a directory-backed feed (desired state). - A file-system watcher detects new
.nupkgfiles and triggers reconciliation (with 1-second debounce). - Nuplane resolves and extracts the package, loads its assemblies, and emits
PackageChangeSetevents. PackageChangeObserverandPluginDiscoveryObserverreact to those events and re-query the authoritative catalog surfaces.- The
/catalog/pluginsendpoint exposes allIPluginimplementations discovered from the newly loaded packages.
The whole loop — from dropping a file to having the types available through the HTTP surface — takes about a second.
Build and pack the sample plugin
dotnet pack samples/Nuplane.Sample.Plugin/Nuplane.Sample.Plugin.csproj -c Debug
This produces a .nupkg like:
samples/Nuplane.Sample.Plugin/bin/Debug/Nuplane.Sample.Plugin.1.0.0.nupkg
Start the ASP.NET sample
dotnet run --project samples/Nuplane.Sample.AspNetCore/Nuplane.Sample.AspNetCore.csproj
The app is configured (via the Nuplane section in samples/Nuplane.Sample.AspNetCore/appsettings.json) to watch:
packages
Trigger reconciliation by dropping a package
In another shell:
mkdir -p packages
cp samples/Nuplane.Sample.Plugin/bin/Debug/Nuplane.Sample.Plugin.1.0.0.nupkg packages/
Expected behavior:
- The file watcher detects the new
.nupkgand triggers manual reconcile asynchronously. - Nuplane applies any changes and emits
PackageChangeSetevents. PackageChangeObserverlogs the change-set lifecycle.PluginDiscoveryObserverscans changed package contexts forIPluginand logs discovered type names (for example,Nuplane.Sample.Plugin.HelloPlugin).
See:
samples/Nuplane.Sample.AspNetCore/PackageChangeObserver.cssamples/Nuplane.Sample.AspNetCore/PluginDiscoveryObserver.cs
To trigger another cycle, update/remove packages in packages.
⚙️ Phase 2 Operator Guidance
Use these conventions when enabling advanced feed governance:
- Configure deterministic feed priorities and keep names stable across environments.
- Set trust explicitly per feed:
Trusted,Restricted, orUntrusted. - Use untrusted overrides only with scoped intent (
packageorfeed-rule) and always provide an operator reason. - Enable strict outage handling only when you want impacted packages to fail fast while unrelated packages continue.
Lock-file conventions
- Recommended lock path:
./state/nuplane.lock.json(outside source-controlled app code paths). - Commit lock files only for reproducibility workflows where environment parity is required.
- Use
generatemode to refresh lock entries from a known-good cycle. - Use
enforcemode to hold package versions/feed selection stable under feed drift. - Use
strictmode to fail packages missing lock entries and to block hash mismatches. - Rotate lock files intentionally and treat lock updates as auditable operational changes.
⚙️ Phase 4 Operator Guidance (Convergent Runtime Loading)
Use these conventions when enabling cluster-convergent runtime loading:
- Configure a shared desired manifest with exact version pins for deterministic convergence across replicas.
- Update manifests atomically: upload package artifacts first, then write/update the manifest last.
- Use
ConvergenceOptionsto configure manifest path, admin surfaces, optional loader boundary, and poll interval. - Keep loader integration opt-in and default-disabled unless the host explicitly wants Nuplane-managed loading.
- Use
INuplaneAdminOperations(in-process) orNuplane.Admin.AspNetCore(HTTP) for admin reads and manual reconcile triggers. - Monitor convergence through correlation-linked logs, metrics, health transitions, and observer failure events.
- Treat degraded cycles as non-mutating: LKG active state is preserved; impacted scope is explicitly reported.
Phase 4 validation baseline
- Profile:
phase4-convergent-loading-baseline - Replicas: 2+
- Desired input: shared manifest with exact package versions
- Determinism window: 20 unchanged cycles
- Failure injections: manifest invalid, source outage, acquisition failure, loader failure, manual trigger unavailable/rejected
⚙️ Phase 3 Operator Guidance (Optional Loading)
Use these conventions when enabling optional in-process loading:
- Keep loading opt-in and default-disabled unless the host explicitly wants Nuplane-managed loading.
- Use per-package isolated load contexts and configure shared contracts by strong identity (
name,publicKeyToken,majorVersion). - Configure bounded deactivation timeout and continue with unload attempt on timeout.
- Treat
UnloadPendingas degraded and retry pending unload on each reconciliation cycle. - Capture outcome evidence using observer callbacks plus correlation-linked logs/metrics/health.
Phase 3 validation baseline
- Profile:
phase3-loading-baseline - Dataset: 20 active packages (including overlapping dependencies + shared-contract references)
- Window: 10 identical reconciliation cycles
- Failure injection: load failures, unload failures, deactivation timeout events
🛡 Integrity & Trust
Nuplane supports validation hooks:
public interface IPackageValidator
{
Task ValidateAsync(PackageArtifact artifact);
}
Possible implementations:
- Hash validation
- Signature validation
- Allowlist / denylist
- Feed trust enforcement
Nuplane assumes trusted code execution unless your host enforces additional policies.
📊 Observability
Nuplane provides:
- Structured lifecycle logs
- Per-cycle correlation IDs
- Metrics (adds, updates, failures, durations)
- Health state (healthy / degraded)
- Persistent state tracking
🧱 Architecture
Nuplane is modular:
Nuplane.Runtime— control plane + reconciliation loopNuplane.Store— deterministic package storeNuplane.NuGet— NuGet protocol integrationNuplane.Sources.Directory— folder-based desired sourceNuplane.Hosting— DI/Generic Host integrationNuplane.Loading(optional) — assembly loading support
🎯 Design Principles
- Deterministic
- Transactional
- Host-neutral
- Operationally safe
- Minimal abstraction surface
- No accidental framework creep
🚀 Roadmap
See docs/roadmap.md for detailed phase breakdown.
📐 Coding Conventions
See docs/coding-conventions.md for project coding standards and conventions.
License
Nuplane is infrastructure for runtime package reconciliation — clean, predictable, and composable.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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 is compatible. 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 is compatible. 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. |
-
net10.0
- Microsoft.Extensions.Configuration.Binder (>= 10.0.3)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Options (>= 10.0.3)
- Microsoft.Extensions.Resilience (>= 10.1.0)
- NuGet.Frameworks (>= 6.13.1)
- NuGet.Protocol (>= 6.13.1)
- NuGet.Resolver (>= 6.13.1)
- NuGet.Versioning (>= 6.13.1)
- Nuplane.Abstractions (>= 0.0.8)
- Polly.Extensions (>= 8.6.5)
-
net8.0
- Microsoft.Extensions.Configuration.Binder (>= 10.0.3)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Options (>= 10.0.3)
- Microsoft.Extensions.Resilience (>= 10.1.0)
- NuGet.Frameworks (>= 6.13.1)
- NuGet.Protocol (>= 6.13.1)
- NuGet.Resolver (>= 6.13.1)
- NuGet.Versioning (>= 6.13.1)
- Nuplane.Abstractions (>= 0.0.8)
- Polly.Extensions (>= 8.6.5)
-
net9.0
- Microsoft.Extensions.Configuration.Binder (>= 10.0.3)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Options (>= 10.0.3)
- Microsoft.Extensions.Resilience (>= 10.1.0)
- NuGet.Frameworks (>= 6.13.1)
- NuGet.Protocol (>= 6.13.1)
- NuGet.Resolver (>= 6.13.1)
- NuGet.Versioning (>= 6.13.1)
- Nuplane.Abstractions (>= 0.0.8)
- Polly.Extensions (>= 8.6.5)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on Nuplane:
| Package | Downloads |
|---|---|
|
Nuplane.Sources.Directory
Directory-backed feed support for Nuplane, including local .nupkg discovery and file-system change monitoring. |
|
|
Nuplane.Loading
Core assembly loading services for Nuplane, including collectible load contexts and package loading coordination. |
|
|
Nuplane.Admin
Administrative operations surface for Nuplane, including snapshots and manual reconciliation triggers. |
GitHub repositories (1)
Showing the top 1 popular GitHub repositories that depend on Nuplane:
| Repository | Stars |
|---|---|
|
elsa-workflows/elsa-core
The Workflow Engine for .NET
|