Getting Started in Depth
The short introduction is Getting Started. This page walks through a complete application step by step.
CodeLogic is a modular .NET 11 framework for building structured applications with libraries, plugins, configuration, localization, events, and health checks. This guide takes you from zero to a running application.
Installation
Install the package from nuget.org (5.0 is in preview):
dotnet add package CodeLogic --prerelease
Or, to build against a local clone, add a project reference:
<ItemGroup>
<ProjectReference Include="path/to/CodeLogic/src/CodeLogic.csproj" />
</ItemGroup>
Your project should target .NET 11:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net11.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
The 5-Step Boot Sequence
using CodeLogic;
var result = await CodeLogic.InitializeAsync(o =>
{
o.AppVersion = "1.0.0";
o.FrameworkRootPath = "CodeLogic";
});
if (result.ShouldExit) return;
await Libraries.LoadAsync<MyLibrary>();
CodeLogic.RegisterApplication(new MyApp());
await CodeLogic.ConfigureAsync();
await CodeLogic.StartAsync();
if (result.RunHealthCheck)
{
var report = await CodeLogic.GetHealthAsync();
Console.WriteLine(report.ToConsoleString());
await CodeLogic.StopAsync();
return;
}
await Task.Delay(Timeout.Infinite);
What each step does
| Step | Method | What happens |
|---|---|---|
| 1 | InitializeAsync |
Parses CLI args, scaffolds the directory tree on first run, loads framework config, creates LibraryManager |
| 2 | Libraries.LoadAsync<T> |
Registers library types before configure/start |
| 3 | RegisterApplication |
Registers your IApplication implementation |
| 4 | ConfigureAsync |
Discovers DLL libraries, runs OnConfigureAsync on the application and libraries, then generates or loads config/localization files |
| 5 | StartAsync |
Runs OnInitializeAsync then OnStartAsync on libraries first, then the application |
First Run Behavior
On first run, CodeLogic scaffolds the directory tree and continues startup normally. Missing config files are generated with defaults as part of ConfigureAsync().
Typical layout:
YourApp.exe
CodeLogic/
Framework/
CodeLogic.json
CodeLogic.Development.json
logs/
framework.log
Libraries/
CL.YourLibrary/
config.json
localization/
strings.en-US.json
logs/
data/
Application/
config.json
localization/
logs/
data/
Plugins/
Development vs Production Config
The runtime chooses one complete framework config file:
| Condition | File loaded |
|---|---|
Environment Development (DOTNET_ENVIRONMENT, ASPNETCORE_ENVIRONMENT or CODELOGIC_ENVIRONMENT), or UseDevelopmentConfig = true |
CodeLogic.Development.json |
| Anything else (an attached debugger alone does not count) | CodeLogic.json |
CodeLogic.Development.json is a full replacement file, not an overlay or merge. If a section is omitted there, it falls back to the model's default values, not to values from CodeLogic.json.
Example development file:
{
"framework": {
"name": "CodeLogic",
"version": "5.0.29"
},
"logging": {
"mode": "singleFile",
"maxFileSizeMb": 10,
"maxRolledFiles": 5,
"fileNamePattern": "{date:yyyy}/{date:MM}/{date:dd}/{level}.log",
"globalLevel": "Debug",
"enableConsoleOutput": true,
"consoleMinimumLevel": "Debug",
"enableDebugMode": true,
"centralizedDebugLog": false,
"centralizedLogsPath": null,
"includeMachineName": true,
"timestampFormat": "yyyy-MM-dd HH:mm:ss.fff"
},
"localization": {
"defaultCulture": "en-US",
"supportedCultures": ["en-US", "da-DK"],
"autoGenerateTemplates": true
},
"libraries": {
"discoveryPattern": "CL.*",
"enableDependencyResolution": true
},
"healthChecks": {
"enabled": true,
"intervalSeconds": 10
}
}
Add CodeLogic.Development.json to .gitignore.
Your First Application
using CodeLogic.Core.Configuration;
using CodeLogic.Framework.Application;
public class MyApp : IApplication
{
public ApplicationManifest Manifest => new()
{
Id = "myapp",
Name = "My Application",
Version = "1.0.0"
};
public Task OnConfigureAsync(ApplicationContext context)
{
context.Configuration.Register<AppConfig>();
return Task.CompletedTask;
}
public Task OnInitializeAsync(ApplicationContext context)
{
var config = context.Configuration.Get<AppConfig>();
context.Logger.Info($"GreetingName={config.GreetingName}");
return Task.CompletedTask;
}
public Task OnStartAsync(ApplicationContext context) => Task.CompletedTask;
public Task OnStopAsync() => Task.CompletedTask;
public Task<HealthStatus> HealthCheckAsync() => Task.FromResult(HealthStatus.Healthy("Running"));
}
public class AppConfig : ConfigModelBase
{
public string GreetingName { get; set; } = "World";
}
Your First Library
using CodeLogic.Core.Configuration;
using CodeLogic.Framework.Libraries;
public class MyLibrary : ILibrary
{
public LibraryManifest Manifest => new()
{
Id = "CL.MyLibrary",
Name = "My Library",
Version = "1.0.0"
};
public Task OnConfigureAsync(LibraryContext context)
{
context.Configuration.Register<MyLibraryConfig>();
return Task.CompletedTask;
}
public Task OnInitializeAsync(LibraryContext context)
{
var config = context.Configuration.Get<MyLibraryConfig>();
context.Logger.Info($"MaxItems={config.MaxItems}");
return Task.CompletedTask;
}
public Task OnStartAsync(LibraryContext context) => Task.CompletedTask;
public Task OnStopAsync() => Task.CompletedTask;
public Task<HealthStatus> HealthCheckAsync() => Task.FromResult(HealthStatus.Healthy("All good"));
public void Dispose() { }
}
public class MyLibraryConfig : ConfigModelBase
{
public int MaxItems { get; set; } = 100;
}
Useful CLI Flags
| Flag | Description |
|---|---|
--version |
Print version and exit |
--info |
Print framework info and exit |
--health |
Run a health check after startup |
--generate-configs |
Generate missing config files before startup continues |
--generate-configs-force |
Overwrite existing config files with defaults |
--dry-run |
Run ConfigureAsync() only, validate startup inputs, and do not write files |
Minimal Working Example
using CodeLogic;
var result = await CodeLogic.InitializeAsync(o => o.AppVersion = "1.0.0");
if (result.ShouldExit) return;
await CodeLogic.ConfigureAsync();
await CodeLogic.StartAsync();
Console.WriteLine("Running. Press Ctrl+C to stop.");
await Task.Delay(Timeout.Infinite);
No libraries and no application are required to boot the framework itself. Add libraries with Libraries.LoadAsync<T>() and register an application with CodeLogic.RegisterApplication(new MyApp()) when you are ready.