Mohr.Jonas.Spaceshot 2.0.5

dotnet add package Mohr.Jonas.Spaceshot --version 2.0.5
                    
NuGet\Install-Package Mohr.Jonas.Spaceshot -Version 2.0.5
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Mohr.Jonas.Spaceshot" Version="2.0.5" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Mohr.Jonas.Spaceshot" Version="2.0.5" />
                    
Directory.Packages.props
<PackageReference Include="Mohr.Jonas.Spaceshot" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Mohr.Jonas.Spaceshot --version 2.0.5
                    
#r "nuget: Mohr.Jonas.Spaceshot, 2.0.5"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Mohr.Jonas.Spaceshot@2.0.5
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Mohr.Jonas.Spaceshot&version=2.0.5
                    
Install as a Cake Addin
#tool nuget:?package=Mohr.Jonas.Spaceshot&version=2.0.5
                    
Install as a Cake Tool

🚀 Spaceshot - An alternative apphost

About

Spaceshot in an apphost, similar to packages like Microsoft.Extensions.Hosting

Features

  • Dependency injection for services
  • Dynamic service creating / starting / stopping at runtime
  • Minimal, easily maintainable codebase

Dependency injection

Dependency injection is configured via Spaceshot.ConfigurePayload().

Injection strategies

Dependency injection support three strategies:

  • Singleton: The value will be created once during the lifetime of the application
  • Scoped: The value is created once required and will persist until disposed at which point it will be recreated the next time it is required
  • OneShot The value is created every time it is required

Registering values

Values can be injected at startup via Spaceshot.ConfigurePayload() or during runtime via the magic PayloadConfigurator object.

configurator.RegisterSingleton(static (_, _) => LoggerFactory.Create(builder =>
{
    builder.SetMinimumLevel(LogLevel.Trace);
    builder.AddSimpleConsole(conf =>
    {
        conf.IncludeScopes = true;
        conf.SingleLine = false;
    });
}));
configurator.RegisterOneShot(static (type, injector) => injector.Inject<ILoggerFactory>().CreateLogger(type));
configurator.RegisterSingleton(static (_, _) => new ProgramSettings());

The injector

The injector is used to retrieve values from the dependency injection container via its methods:

public TInjectable Inject<TInjectable>() { ... }
public TInjectable InjectKeyed<TInjectable>(string key) { ... }

Magic objects

Magic object are objects that can be retrieved via dependency injection and are always automatically available.

The Spaceship object

The spaceship object is a special object that can be retrieved at runtime.
It functions as a controller for the running apphost, allowing the user to stop it.

The PayloadEvictor

The payload evictor can be used to evict values from the dependency injection container, making this tool essential for using Scoped values.

The PayloadConfigurator

The payload configurator is used to add dependency injection values at runtime.

Services

Services are configured via Spaceshot.ConfigureControls(). The available services are:

  • ISetup: Runs once at apphost start, used to set up dependencies, create required files, parsing arguments, ...
  • IAsyncSetup: Same as ISetup, but runs asynchronously
  • ITeardown: Runs once at apphost stop, used to save files, dispose objects, ...
  • IAsyncTeardown: Same as ITeardown, but runs asynchronously
  • IBackgroundService: Combination of ISetup and ITeardown
  • IAsyncBackground: Same as IBackgroundService, but runs asynchronously
spaceshot.ConfigureControls(static configurator =>
{
    configurator.RegisterSetup<ParseCliSetup>(static _ => new ParseCliSetup());
    configurator.RegisterAsyncTeardown<DBDisposer>(static injector => new DBDisposer(
        injector.Inject<ILogger>(),
        injector.Inject<SqliteConnection>()
    ));
});

Configuring startup / teardown sequence

The startup and teardown sequence can be configured via the PriorityAttribute.
The attribute supports the following priorities, execute in the following order:

  • Highest
  • High
  • Medium
  • Low
  • Lowest

Assuming you want to configure the ParseCliSetup to run first, the PriorityAttribute can be used as follows:

[Priority(Priority.Highest)]
internal sealed class ParseCliSetup : ISetup
{
    public void Setup() { ... }
}

Full example

internal static class Program
{
    private static void Main()
    {
        using var factory = LoggerFactory.Create(builder =>
            builder.AddSimpleConsole(conf =>
            {
                conf.IncludeScopes = true;
                conf.SingleLine = false;
            }));
        var logger = factory.CreateLogger(typeof(Spaceshot));
        var spaceship = new Spaceshot(logger);
        spaceship.ConfigurePayload(static configurator =>
        {
            configurator.RegisterSingleton(static (_, _) => LoggerFactory.Create(builder =>
            {
                builder.SetMinimumLevel(LogLevel.Trace);
                builder.AddSimpleConsole(conf =>
                {
                    conf.IncludeScopes = true;
                    conf.SingleLine = false;
                });
            }));
            configurator.RegisterOneShot(static (type, injector) => injector.Inject<ILoggerFactory>().CreateLogger(type));
            configurator.RegisterSingleton(static (_, _) => new ProgramSettings());
        });
        spaceship.ConfigureControls(static configurator =>
        {
            configurator.RegisterSetup(static injector => new SigtermCatcher(
                    injector.Inject<ILogger>(),
                    injector.Inject<Spaceship>()
                ));
            configurator.RegisterAsyncSetup(static injector => new DbMigrator(
                injector.Inject<ILogger>(),
                injector.Inject<PayloadConfigurator>(),
                injector.Inject<ProgramSettings>()
            ));
            configurator.RegisterAsyncTeardown(static injector => new DBDisposer(
                injector.Inject<ILogger>(),
                injector.Inject<SqliteConnection>()
            ));
        });
        spaceship.LiftOff();
    }
}
Product 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.5 333 9/17/2025
2.0.4 321 9/17/2025
2.0.3 319 9/17/2025
2.0.2 321 9/17/2025
2.0.1 321 9/17/2025