Jasper in Console Applications Edit on GitHub

At this time, the Jasper team is focused on hosting applications either in IIS (or nginx) or as a console application that would be suitable for running in a Docker container. To that end, we've added the JasperAgent static class in the external Jasper.CommandLine Nuget library as a helper for quickly standing up Jasper applications in a console application.

The sample usage from the getting started topic would look like this:

using Jasper.CommandLine;

namespace MyApp
    class Program
        static int Main(string[] args)
            // This bootstraps and runs the Jasper
            // application as defined by MyAppRegistry
            // until the executable is stopped
            return JasperAgent.Run<MyAppRegistry>(args);

At runtime, JasperAgent uses the JasperRegistry you hand it to bootstrap a JasperRuntime and run the application until the console process is stopped.

You can also use the command line arguments to customize how the application runs like this:

static int Main(string[] args)
    return JasperAgent.Run<MyAppRegistry>(args, _ =>
        if (args.Length == 1)
            _.EnvironmentName = args[0];

Or like this:

static int Main(string[] args)
    // This gives you the ability to programmatically
    // construct the application based on the command line
    // arguments
    var registry = new JasperRegistry();

    return JasperAgent.Run(args, registry);

Let's say that your Jasper application compiles to MyApp.exe and uses the JasperAgent class to run the commands. In that case you can run your application simply by typing MyApp at the command line with no arguments.

However, the Jasper.CommandLine library adds some additional commands for running, validating, or describing the running application.

Overriding the Environment Name

For example, you can also use this syntax to run your application in "Development" mode:

MyApp run --environment Development


MyApp run -e Development

If you run this command, your application will start with JasperRegistry.EnvironmentName equal to Development. If you programmatically set the environment name in your JasperRegistry, that setting will win out over the command line flag.

Running with Verbose Console Tracing

Likewise, to see more verbose information on start up and runtime console tracing, use:

MyApp run --verbose


MyApp run -v

The -v / --verbose flags add console and debug logging to your system. It's the equivalent to calling:

Overriding the LogLevel

You can also override the log level of your application to any valid value of the LogLevel enumeration like this:

MyApp run --log-level Information

Validating the Configured Application

You may want to simply try to bootstrap the application and run all the environment tests and report out the results. That syntax is:

MyApp validate

which also respects the same --environment and --verbose flags as the run command. This command will bootstrap the application, run all the environment tests and start up validations, report on the success or failure, and shut down the application. Do note that if any environment tests fail, this command will return a non-zero return code that should be sufficient to let any build scripting tool you're using know that the validation failed.

List Registered Services

Jasper only supports the Lamar container (the replacement for the venerable StructureMap container). To query the current state of service registrations, use this command:

MyApp services

And again, this command respects both the --environment and --verbose flags


See Dynamic Subscriptions for information about the subscriptions command and related workflow for exporting, updating, or validating dynamic subscriptions.

Preview Generated Code

One of the easiest ways to debug message or HTTP handlers -- or just to understand their behavior -- is to read the generated code that Jasper is using to actually handle a specific message type or HTTP route. You can preview that code by using this command:

dotnet run -- code

Or to only see the code for message handlers:

dotnet run -- code messages

Or to only see the code for any HTTP handlers:

dotnet run -- code routes

Finally, to dump the results to a file, use the --file flag like this:

dotnet run -- code --file generated.cs


dotnet run -- code -f generated.cs

As usual, this command also respects both the --environment and --verbose flags

Custom Commands

The Jasper.Console package uses the Oakton library for its command line support. You can add custom commands to your Jasper application by simply including OaktonCommand<T> classes in either the main application assembly or in any assembly that is decorated with the [JasperModule] attribute like so:


or without any kind of extension like so:


If you want to write a command that uses the actual Jasper application, use the JasperInput class as either the input to your command or as the superclass to your input class:

public class JasperInput
    public JasperRegistry Registry { get; set; }

    [Description("Use to override the ASP.Net Environment name")]
    public string EnvironmentFlag { get; set; }

    [Description("Write out much more information at startup and enables console logging")]
    public bool VerboseFlag { get; set; }

    [Description("Override the log level")]
    public LogLevel? LogLevelFlag { get; set; }

    public JasperRuntime BuildRuntime()
        // SAMPLE: what-the-cli-is-doing

        // The --log-level flag value overrides your application's
        // LogLevel
        if (LogLevelFlag.HasValue)
            Registry.ConfigureLogging(x => x.SetMinimumLevel(LogLevelFlag.Value));

        if (VerboseFlag)
            Console.WriteLine("Verbose flag is on.");

            // The --verbose flag adds console and
            // debug logging, as well as setting
            // the minimum logging level down to debug
            Registry.ConfigureLogging(x =>


        // The --environment flag is used to set the environment
        // property on the IHostedEnvironment within your system
        if (EnvironmentFlag.IsNotEmpty())

To make that more concrete, here is how the built in services command uses JasperInput type to build out and use the running system:

[Description("Display the known StructureMap service registrations")]
public class ServicesCommand : OaktonCommand<JasperInput>
    public override bool Execute(JasperInput input)
        input.Registry.Settings.Alter<MessagingSettings>(_ =>
            _.ThrowOnValidationErrors = false;

        using (var runtime = input.BuildRuntime())

        return true;

Do note that the command will be responsible for disposing and shutting down the running JasperRuntime.