GarminRunerz.Workout.Services
1.0.0
dotnet add package GarminRunerz.Workout.Services --version 1.0.0
NuGet\Install-Package GarminRunerz.Workout.Services -Version 1.0.0
<PackageReference Include="GarminRunerz.Workout.Services" Version="1.0.0" />
<PackageVersion Include="GarminRunerz.Workout.Services" Version="1.0.0" />
<PackageReference Include="GarminRunerz.Workout.Services" />
paket add GarminRunerz.Workout.Services --version 1.0.0
#r "nuget: GarminRunerz.Workout.Services, 1.0.0"
#:package GarminRunerz.Workout.Services@1.0.0
#addin nuget:?package=GarminRunerz.Workout.Services&version=1.0.0
#tool nuget:?package=GarminRunerz.Workout.Services&version=1.0.0
GarminRunerz.Workout.Services
A .NET library providing high-level services for generating and building Garmin workout structures. This library builds upon the GarminRunerz.Workout.Models foundation to offer a fluent API for workout construction and intelligent workout generation from training plans.
Overview
GarminRunerz.Workout.Services is designed to simplify the creation of complex Garmin workout structures through two main approaches:
- Fluent Workout Builder: A chainable API for manually constructing workouts with warm-ups, intervals, and cool-downs
- Workout Generator Service: An intelligent service that generates complete workouts from training plan specifications
Features
- Fluent API: Intuitive, chainable methods for workout construction
- Training Plan Integration: Generate workouts from structured training data
- Built-in Pace Constants: Pre-defined pace zones for common training intensities
- Dependency Injection Ready: Full support for .NET dependency injection
- Comprehensive Logging: Integrated logging for workout generation processes
- Automatic Calculations: Smart estimation of workout duration and distance
- NuGet Package: Available as a .NET package for easy integration
Installation
Install the package via NuGet Package Manager:
Install-Package GarminRunerz.Workout.Services
Or via .NET CLI:
dotnet add package GarminRunerz.Workout.Services
Dependencies
This package depends on:
GarminRunerz.Workout.Models
- Core workout data modelsMicrosoft.Extensions.DependencyInjection.Abstractions
- Dependency injection supportMicrosoft.Extensions.Logging.Abstractions
- Logging support
Quick Start
Dependency Injection Setup
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using GarminRunerz.Workout.Services;
var services = new ServiceCollection();
// Add logging
services.AddLogging(builder => builder.AddConsole());
// Register services
services.AddScoped<IWorkoutBuilder, WorkoutBuilder>();
services.AddScoped<IWorkoutGeneratorService, WorkoutGeneratorService>();
var serviceProvider = services.BuildServiceProvider();
Fluent Workout Builder
using GarminRunerz.Workout.Services;
using GarminRunerz.Workout.Models;
// Create a workout using the fluent builder
var builder = serviceProvider.GetRequiredService<IWorkoutBuilder>();
var workout = builder
.Reset("5K Interval Training")
.WithSport("running")
.AddWarmUp(600) // 10 minutes warm-up
.AddIntervals(
repetitions: 5,
runSeconds: 180, // 3 minutes hard
restSeconds: 90, // 1.5 minutes recovery
targetPaceMinPerKm: 4.0m, // 4:00 min/km target pace
toleranceMinPerKm: 0.15m // ±9 seconds tolerance
)
.AddCoolDown(600) // 10 minutes cool-down
.WithEstimates(durationSecs: 2250, distanceMeters: 8000)
.Build();
Console.WriteLine($"Workout: {workout.WorkoutName}");
Console.WriteLine($"Estimated Duration: {workout.EstimatedDurationInSecs} seconds");
Console.WriteLine($"Estimated Distance: {workout.EstimatedDistanceInMeters} meters");
Workout Generator Service
using GarminRunerz.Workout.Services;
using GarminRunerz.Workout.Services.Models;
// Create a custom workout specification
var customWorkout = new CustomWorkout
{
WeekNumber = 4,
RunType = RunType.Intervals,
Repetitions = 6,
RunDuration = 240, // 4 minutes hard intervals
CoolDownDuration = 120, // 2 minutes recovery
Pace = 3.85m, // 3:51 min/km (close to VMA pace)
Description = "Week 4 VMA intervals"
};
// Generate the complete workout
var generator = serviceProvider.GetRequiredService<IWorkoutGeneratorService>();
var workout = generator.GenerateWorkoutsFromPlanning(customWorkout);
Console.WriteLine($"Generated: {workout.WorkoutName}");
Console.WriteLine($"Description: {workout.Description}");
API Reference
IWorkoutBuilder
The fluent builder interface for constructing workouts step by step.
Methods
IWorkoutBuilder Reset(string workoutName)
- Initializes a new workout with the given name
- Resets all previous state
- Returns the builder for chaining
IWorkoutBuilder WithAuthor(Author author)
- Sets the workout author information
- Returns the builder for chaining
IWorkoutBuilder WithSport(string sportTypeKey = "running", int sportTypeId = 1, int displayOrder = 1)
- Configures the sport type for the workout
- Defaults to running if not specified
- Returns the builder for chaining
IWorkoutBuilder WithTimestamps(DateTime utcNow)
- Sets creation and update timestamps
- Returns the builder for chaining
IWorkoutBuilder WithEstimates(int durationSecs, int distanceMeters)
- Sets estimated duration and distance
- Returns the builder for chaining
IWorkoutBuilder AddWarmUp(double durationSeconds)
- Adds a warm-up step with no specific target
- Creates a "lap button" end condition
- Returns the builder for chaining
IWorkoutBuilder AddIntervals(int repetitions, double runSeconds, double restSeconds, decimal targetPaceMinPerKm, decimal toleranceMinPerKm = 0.15m)
- Adds a repeat group containing interval and rest steps
- Creates pace-targeted intervals with the specified tolerance
- Returns the builder for chaining
IWorkoutBuilder AddCoolDown(double durationSeconds)
- Adds a cool-down step with no specific target
- Creates a "lap button" end condition
- Returns the builder for chaining
Workout Build()
- Returns the completed workout object
- Does not reset the builder state
IWorkoutGeneratorService
Service interface for generating workouts from training plan data.
Methods
Workout GenerateWorkoutsFromPlanning(CustomWorkout customWorkout, int? estimatedDuration = null, int? estimatedDistance = null)
- Generates a complete workout from training plan specifications
- Automatically calculates duration and distance if not provided
- Includes standard 15-minute warm-up and 10-minute cool-down
- Returns a fully constructed workout
Built-in Pace Constants
The WorkoutGeneratorService
includes pre-defined pace constants for common training zones:
public static readonly decimal MarathonPace = 4.66m; // 4:40 min/km
public static readonly decimal HalfMarathonPace = 4.25m; // 4:15 min/km
public static readonly decimal VMAPace = 3.93m; // 3:55 min/km
public static readonly decimal EFPace = 6.0m; // 6:00 min/km (Easy/Recovery)
Models
CustomWorkout
Represents a training plan specification that can be converted into a Garmin workout.
Properties:
Id
: Unique identifierWeekNumber
: Training plan week numberRunType
: Type of run (see RunType enum)TotalDuration
: Total planned durationRepetitions
: Number of interval repetitionsRunDuration
: Duration of each work interval (seconds)CoolDownDuration
: Duration of each rest interval (seconds)Pace
: Target pace in minutes per kilometerSpeed
: Target speed (calculated)Description
: Human-readable description
RunType Enum
Defines different types of training runs:
public enum RunType
{
[Description("VMA")]
Intervals = 1, // High-intensity intervals
[Description("EF")]
Easy = 2, // Easy/endurance pace
[Description("Recovery")]
Recovery = 4, // Recovery runs
[Description("Active Recovery")]
Steady = 8, // Steady state runs
[Description("Tempo")]
Tempo = 16, // Tempo/threshold runs
[Description("Long run")]
LongRun = 32, // Long endurance runs
[Description("Race")]
Race = 64, // Race pace runs
Other = 128 // Other types
}
Advanced Usage
Custom Author Information
var customAuthor = new Author
{
UserProfilePk = 12345,
DisplayName = "CoachAI",
FullName = "Training Coach",
UserPro = true,
VivokidUser = false
};
var workout = builder
.Reset("Custom Authored Workout")
.WithAuthor(customAuthor)
.AddWarmUp(300)
.Build();
Multi-Sport Workouts
// Currently, the builder focuses on single-sport workouts
// For multi-sport, you would need to create multiple segments manually
var workout = builder
.Reset("Triathlon Brick Workout")
.WithSport("cycling")
.AddWarmUp(600)
.AddIntervals(3, 1200, 300, 2.5m) // Cycling intervals
.Build();
// Then create a separate running workout
var runWorkout = builder
.Reset("Triathlon Run")
.WithSport("running")
.AddIntervals(2, 600, 120, 4.2m) // Running intervals
.Build();
Pace Calculations
The services automatically handle pace conversions from minutes/km to meters/second for Garmin compatibility:
// Input: 4:00 min/km pace with ±0:15 tolerance
// Automatically converts to:
// - Low target: ~4.17 m/s (3:45 min/km)
// - High target: ~3.85 m/s (4:15 min/km)
var workout = builder
.AddIntervals(5, 300, 180, 4.0m, 0.25m) // 4:00 ± 0:15
.Build();
Logging Integration
The generator service provides detailed logging for troubleshooting:
// Configure logging to see generation details
services.AddLogging(builder =>
{
builder.AddConsole();
builder.SetMinimumLevel(LogLevel.Information);
});
// Logs will include:
// - Workout generation parameters
// - Calculation results
// - Warning for edge cases (e.g., zero repetitions)
Requirements
- .NET 9.0 or higher
- GarminRunerz.Workout.Models package
- Microsoft.Extensions.DependencyInjection.Abstractions
- Microsoft.Extensions.Logging.Abstractions
Best Practices
1. Use Dependency Injection
Always register services in your DI container rather than creating instances manually:
// ✅ Good
services.AddScoped<IWorkoutBuilder, WorkoutBuilder>();
var builder = serviceProvider.GetRequiredService<IWorkoutBuilder>();
// ❌ Avoid
var builder = new WorkoutBuilder();
2. Reset Builder Between Workouts
The WorkoutBuilder
is stateful. Always call Reset()
when starting a new workout:
// ✅ Good
var workout1 = builder.Reset("Workout 1").AddWarmUp(300).Build();
var workout2 = builder.Reset("Workout 2").AddWarmUp(600).Build();
// ❌ Problematic - state carries over
var workout1 = builder.AddWarmUp(300).Build();
var workout2 = builder.AddWarmUp(600).Build(); // Contains both warm-ups
3. Validate Input Data
Always validate CustomWorkout
data before generating:
if (customWorkout.Repetitions <= 0)
{
throw new ArgumentException("Repetitions must be positive");
}
if (customWorkout.Pace <= 0)
{
throw new ArgumentException("Pace must be positive");
}
4. Use Built-in Pace Constants
Leverage the pre-defined pace constants for consistency:
// ✅ Good - uses built-in constant
var workout = generator.GenerateWorkoutsFromPlanning(new CustomWorkout
{
Pace = WorkoutGeneratorService.VMAPace,
// ... other properties
});
// ✅ Also good - custom pace with explanation
var workout = generator.GenerateWorkoutsFromPlanning(new CustomWorkout
{
Pace = 3.75m, // Custom race pace
// ... other properties
});
Contributing
Contributions are welcome! Please feel free to submit pull requests or open issues for bugs and feature requests.
License
This project is open source. Please refer to the license file for more information.
Related Projects
- GarminRunerz.Workout.Models - Core data models for Garmin workouts
- Other libraries in the GarminRunerz ecosystem for working with Garmin fitness data
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | 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 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. |
-
net9.0
- GarminRunerz.Workout.Models (>= 1.1.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.9)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.9)
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
1.0.0 | 2 | 9/16/2025 |
Initial release of GarminRunerz.Workout.Services with fluent workout builder and intelligent workout generation capabilities.