FlexRender.DependencyInjection
0.2.0
See the version list below for details.
dotnet add package FlexRender.DependencyInjection --version 0.2.0
NuGet\Install-Package FlexRender.DependencyInjection -Version 0.2.0
<PackageReference Include="FlexRender.DependencyInjection" Version="0.2.0" />
<PackageVersion Include="FlexRender.DependencyInjection" Version="0.2.0" />
<PackageReference Include="FlexRender.DependencyInjection" />
paket add FlexRender.DependencyInjection --version 0.2.0
#r "nuget: FlexRender.DependencyInjection, 0.2.0"
#:package FlexRender.DependencyInjection@0.2.0
#addin nuget:?package=FlexRender.DependencyInjection&version=0.2.0
#tool nuget:?package=FlexRender.DependencyInjection&version=0.2.0
FlexRender
A .NET library for rendering images from YAML templates with flexbox-like layout system. Perfect for generating receipts, labels, tickets, and other structured documents.
Features
- YAML Templates - Define layouts in readable YAML format
- Flexbox Layout - Row/column direction, wrap, justify, align, gap
- Template Engine - Variables, loops (
type: each), conditionals (type: if) - Multiple Content Types - Text, images, QR codes, barcodes
- Output Formats - PNG, JPEG, BMP, Raw
- CLI Tool - Render templates from command line
- AOT Compatible - No reflection, works with Native AOT
- Modular Architecture - Install only what you need
Examples
| Receipt | Dynamic Receipt | Ticket | Label |
|---|---|---|---|
<details> <summary>Feature Showcase (click to expand)</summary>
</details>
All examples are in the examples/ directory. Render them with the CLI:
flexrender render examples/receipt.yaml -d examples/receipt-data.json -o examples/output/receipt.png
flexrender render examples/ticket.yaml -d examples/ticket-data.json -o examples/output/ticket.png
flexrender render examples/receipt-dynamic.yaml -d examples/receipt-dynamic-data.json -o examples/output/receipt-dynamic.png
The receipt-dynamic.yaml demonstrates AST-level control flow with type: each for item lists and type: if for conditional sections.
Installation
All-in-one (recommended)
dotnet add package FlexRender
Individual packages
| Package | Description |
|---|---|
FlexRender.Core |
Layout engine, 0 external dependencies |
FlexRender.Yaml |
YAML template parser |
FlexRender.Skia |
SkiaSharp renderer |
FlexRender.QrCode |
QR code support |
FlexRender.Barcode |
Barcode support |
FlexRender.Http |
HTTP/HTTPS resource loading |
FlexRender.DependencyInjection |
Microsoft DI integration |
# Example: install only the core engine and YAML parser
dotnet add package FlexRender.Core
dotnet add package FlexRender.Yaml
# Or install the Skia renderer
dotnet add package FlexRender.Skia
Linux / Docker
SkiaSharp requires native libraries on Linux. If you get DllNotFoundException: libSkiaSharp, add the native assets package:
# Standard Linux (requires system fontconfig/freetype)
dotnet add package SkiaSharp.NativeAssets.Linux
# Minimal containers without system libs
dotnet add package SkiaSharp.NativeAssets.Linux.NoDependencies
CLI tool
dotnet tool install -g FlexRender.Cli
Quick Start
1. Create a template (receipt.yaml)
template:
name: "receipt"
version: 1
canvas:
fixed: width
width: 300
background: "#ffffff"
layout:
- type: flex
padding: 20
gap: 10
children:
- type: text
content: "{{shopName}}"
font: bold
size: 1.5em
align: center
- type: flex
gap: 4
children:
- type: each
array: items
as: item
children:
- type: flex
direction: row
justify: space-between
children:
- type: text
content: "{{item.name}}"
- type: text
content: "{{item.price}} $"
- type: text
content: "Total: {{total}} $"
font: bold
size: 1.2em
align: right
- type: qr
data: "{{paymentUrl}}"
size: 100
2. Render with code
// Build renderer with fluent API
var render = new FlexRenderBuilder()
.WithBasePath("./templates")
.WithSkia(skia => skia
.WithQr()
.WithBarcode())
.Build();
var data = new ObjectValue
{
["shopName"] = "My Shop",
["total"] = 1500,
["paymentUrl"] = "https://pay.example.com/123",
["items"] = new ArrayValue(
new ObjectValue { ["name"] = "Product 1", ["price"] = 500 },
new ObjectValue { ["name"] = "Product 2", ["price"] = 1000 })
};
// Render to PNG bytes
byte[] pngBytes = await render.RenderFile("receipt.yaml", data);
await File.WriteAllBytesAsync("receipt.png", pngBytes);
3. With Dependency Injection
// Program.cs
services.AddFlexRender(builder => builder
.WithBasePath("/app/templates")
.WithSkia(skia => skia
.WithQr()
.WithBarcode()));
// In your service
public class ReceiptService(IFlexRender render)
{
public async Task<byte[]> Generate(ReceiptData data)
{
var values = MapToObjectValue(data);
return await render.RenderFile("receipt.yaml", values);
}
}
4. Or use CLI
flexrender render receipt.yaml -d data.json -o receipt.png
Output Formats
| Format | Extension | Description |
|---|---|---|
| PNG | .png |
Lossless compression, best quality |
| JPEG | .jpg |
Lossy compression, smaller file size |
| BMP | .bmp |
Uncompressed bitmap |
| Raw | .raw |
Raw BGRA pixel data (4 bytes per pixel) |
The Raw format outputs uncompressed pixel data in BGRA order (Blue, Green, Red, Alpha), 4 bytes per pixel, row by row from top to bottom. Useful for direct hardware integration or custom processing pipelines.
Template Syntax
Canvas Settings
canvas:
fixed: width # or height - which dimension is fixed
size: 300 # size in pixels
background: "#ffffff" # background color
Text Element
- type: text
content: "Hello {{name}}!"
font: main # font reference
size: 1.2em # pixels, em, or percentage
color: "#000000"
align: center # left/center/right
wrap: true
overflow: ellipsis # ellipsis/clip/visible
maxLines: 2
rotate: none # none/left/right/flip or degrees
Flex Container
- type: flex
direction: row # row/column
wrap: wrap # nowrap/wrap/wrap-reverse
gap: 10
padding: 5%
justify: space-between # start/center/end/space-between/space-around/space-evenly
align: center # start/center/end/stretch/baseline
children:
- type: text
content: "Item"
flex:
grow: 1
shrink: 0
basis: auto
QR Code
- type: qr
data: "{{url}}"
size: 100
errorCorrection: M # L/M/Q/H
foreground: "#000000"
background: "#ffffff"
Barcode
- type: barcode
data: "{{ean13}}"
format: ean13 # ean13/ean8/code128/code39/upc
width: 200
height: 80
showText: true
foreground: "#000000"
background: "#ffffff"
Image
- type: image
src: "logo.png" # or base64 from data
width: 80%
height: auto
fit: contain # contain/cover/fill/none
Template Expressions
Variable Substitution
# Simple variable
content: "Hello {{name}}"
# Nested access
content: "City: {{user.address.city}}"
# Array index
content: "First: {{items[0].name}}"
Loops (type: each)
# Iterate over array
- type: each
array: items # path to array in data
as: item # variable name for current item
children:
- type: text
content: "{{item.name}}: {{item.price}}"
# Loop variables: @index, @first, @last
- type: each
array: items
as: item
children:
- type: text
content: "{{@index}}. {{item.name}}"
Conditionals (type: if)
# Simple truthy check
- type: if
condition: discount
then:
- type: text
content: "Discount: {{discount}}%"
# With else branch
- type: if
condition: premium
then:
- type: text
content: "Premium member"
else:
- type: text
content: "Regular member"
# Equality check
- type: if
condition: status
equals: "paid"
then:
- type: text
content: "Payment received"
color: "#22c55e"
# Chained else-if
- type: if
condition: status
equals: "paid"
then:
- type: text
content: "PAID"
color: "#22c55e"
elseIf:
condition: status
equals: "pending"
then:
- type: qr
data: "{{paymentUrl}}"
size: 100
else:
- type: text
content: "Payment required"
color: "#ef4444"
CLI Commands
# Render template
flexrender render template.yaml -d data.json -o output.png
flexrender render template.yaml -d data.json -o output.jpg --quality 90
flexrender render template.yaml -d data.json -o output.bmp
# With base path for resolving relative fonts/images
flexrender render templates/receipt.yaml --base-path templates -o output.png
# Validate template
flexrender validate template.yaml
# Show template info
flexrender info template.yaml
# Debug layout - shows element bounds and hierarchy
flexrender debug-layout template.yaml -d data.json
# Watch mode - re-render on changes
flexrender watch template.yaml -d data.json -o preview.png
# Global options
--verbose, -v # Verbose output
--fonts <dir> # Custom fonts directory
--scale <float> # Scale factor (e.g., 2.0 for retina)
--base-path <dir> # Base path for resolving relative file references
API Reference
FlexRenderBuilder (recommended)
// Minimal setup
var render = new FlexRenderBuilder()
.WithSkia()
.Build();
// Full configuration
var render = new FlexRenderBuilder()
.WithHttpLoader() // Enable HTTP resource loading
.WithEmbeddedLoader(typeof(Program).Assembly) // Load from embedded resources
.WithBasePath("./templates") // Base path for file resolution
.WithLimits(limits => limits.MaxRenderDepth = 200)
.WithSkia(skia => skia
.WithQr() // Enable QR code support
.WithBarcode()) // Enable barcode support
.Build();
// Render from YAML file (requires FlexRender.Yaml package)
byte[] png = await render.RenderFile("receipt.yaml", data);
byte[] jpg = await render.RenderFile("receipt.yaml", data, ImageFormat.Jpeg);
// Render from YAML string
byte[] png = await render.RenderYaml(yamlString, data);
// Render from parsed template (for caching)
var parser = new TemplateParser();
var template = parser.Parse(yamlString);
byte[] png = await render.Render(template, data);
// Sandboxed mode (no file system access)
var sandboxed = new FlexRenderBuilder()
.WithoutDefaultLoaders()
.WithEmbeddedLoader(typeof(Program).Assembly)
.WithSkia()
.Build();
Dependency Injection
// Basic registration
services.AddFlexRender(builder => builder
.WithSkia(skia => skia.WithQr().WithBarcode()));
// With service provider access
services.AddFlexRender((sp, builder) =>
{
var config = sp.GetRequiredService<IConfiguration>();
builder
.WithBasePath(config["FlexRender:BasePath"] ?? "./templates")
.WithSkia(skia => skia.WithQr().WithBarcode());
});
// Inject IFlexRender
public class MyService(IFlexRender render)
{
public Task<byte[]> GenerateImage(ObjectValue data)
=> render.RenderFile("template.yaml", data);
}
TemplateValue Types
// String
TemplateValue str = "hello"; // implicit conversion
TemplateValue str = new StringValue("hello");
// Number
TemplateValue num = 42; // implicit from int
TemplateValue num = 3.14; // implicit from double
// Boolean
TemplateValue flag = true; // implicit conversion
// Null
TemplateValue nil = NullValue.Instance;
// Array
var array = new ArrayValue("a", "b", "c");
int count = array.Count;
TemplateValue first = array[0];
// Object
var obj = new ObjectValue
{
["name"] = "John",
["age"] = 30,
["active"] = true
};
TemplateValue name = obj["name"];
bool has = obj.ContainsKey("name");
License
MIT
| 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 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 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
- FlexRender.Core (>= 0.2.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.2)
-
net8.0
- FlexRender.Core (>= 0.2.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on FlexRender.DependencyInjection:
| Package | Downloads |
|---|---|
|
FlexRender
All-in-one FlexRender package. Linux/Docker: add SkiaSharp.NativeAssets.Linux to your project. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.8.0 | 86 | 2/12/2026 |
| 0.7.2 | 305 | 2/11/2026 |
| 0.7.1 | 100 | 2/11/2026 |
| 0.7.0 | 102 | 2/11/2026 |
| 0.6.0 | 109 | 2/10/2026 |
| 0.5.2 | 112 | 2/10/2026 |
| 0.5.1 | 102 | 2/10/2026 |
| 0.5.0 | 102 | 2/10/2026 |
| 0.4.1 | 108 | 2/7/2026 |
| 0.3.1 | 122 | 2/6/2026 |
| 0.3.0 | 106 | 2/5/2026 |
| 0.2.0 | 130 | 2/5/2026 |
| 0.1.0 | 113 | 2/5/2026 |
| 0.0.4 | 107 | 2/4/2026 |
| 0.0.3 | 158 | 2/4/2026 |