Skip to content

CLI Templates

Gryd.IO provides CLI templates for dotnet new to quickly scaffold new projects with the correct structure and dependencies.

Installation

From NuGet (Production)

Install all Gryd.IO templates from NuGet:

bash
dotnet new install Gryd.IO.Templates

From Local Packages (Development)

If you're developing or testing locally, install from the local-packages folder:

bash
# Navigate to the Gryd.IO repository
cd /path/to/Gryd.IO

# Install each template individually
dotnet new install ./templates/gryd-api
dotnet new install ./templates/gryd-minimal
dotnet new install ./templates/gryd-module

Verify Installation

List all installed Gryd templates:

bash
dotnet new list gryd

Expected output:

Template Name    Short Name     Language  Tags
--------------   -----------    --------  ----
Gryd API         gryd-api       [C#]      Web/API/Gryd
Gryd Minimal     gryd-minimal   [C#]      Web/API/Gryd
Gryd Module      gryd-module    [C#]      Library/Gryd/Module

Available Templates

TemplateShort NameDescription
Gryd APIgryd-apiComplete API with Auth + Crud modules
Gryd Minimalgryd-minimalMinimal API with Core packages only
Gryd Modulegryd-moduleClean Architecture module structure

gryd-api

Complete API template with optional GrydAuth and GrydCrud integration, Docker support, and database configuration.

Usage

bash
# Create with defaults (Auth + Crud + PostgreSQL + Docker)
dotnet new gryd-api -n MyApiProject

# Create without authentication
dotnet new gryd-api -n MyApiProject --IncludeAuth false

# Create with SQL Server instead of PostgreSQL
dotnet new gryd-api -n MyApiProject --UsePostgres false --UseSqlServer true

# Create without Docker support
dotnet new gryd-api -n MyApiProject --IncludeDocker false

Parameters

ParameterTypeDefaultDescription
--IncludeAuthbooltrueInclude GrydAuth for authentication/authorization
--IncludeCrudbooltrueInclude GrydCrud for CRUD operations
--UsePostgresbooltrueConfigure PostgreSQL as database
--UseSqlServerboolfalseConfigure SQL Server as database
--IncludeDockerbooltrueInclude Dockerfile and docker-compose.yml

Generated Structure

MyApiProject/
├── MyApiProject.csproj          # Project with Gryd packages
├── Program.cs                    # Startup with DI configuration
├── appsettings.json             # Production configuration
├── appsettings.Development.json # Development configuration
├── README.md                    # Project documentation
├── Controllers/
│   └── ProductsController.cs    # Example CRUD controller
├── Data/
│   └── AppDbContext.cs          # EF Core DbContext
├── Domain/
│   └── Product.cs               # Example entity
├── DTOs/
│   └── ProductDtos.cs           # DTOs for Product entity
├── Dockerfile                   # (if IncludeDocker=true)
├── docker-compose.yml           # (if IncludeDocker=true)
└── .dockerignore                # (if IncludeDocker=true)

Program.cs Example

csharp
var builder = WebApplication.CreateBuilder(args);

// Add Gryd Core
builder.Services.AddGrydCore();
builder.Services.AddDbContext<AppDbContext>(options => 
    options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));

// Add GrydAuth (if IncludeAuth=true)
builder.Services.AddGrydAuth(builder.Configuration);

// Add GrydCrud (if IncludeCrud=true)
builder.Services.AddGrydCrud();
builder.Services.AddCrudFor<Product, ProductDto, CreateProductDto, UpdateProductDto>();

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthentication();  // if IncludeAuth=true
app.UseGrydAuth();        // if IncludeAuth=true
app.UseAuthorization();
app.MapControllers();

app.Run();

gryd-minimal

Minimal API template with only Gryd.Core packages. Perfect for microservices or simple APIs that don't need full CRUD or authentication features.

Usage

bash
# Create with defaults (PostgreSQL)
dotnet new gryd-minimal -n MyMinimalApi

# Create with SQL Server
dotnet new gryd-minimal -n MyMinimalApi --UsePostgres false --UseSqlServer true

Parameters

ParameterTypeDefaultDescription
--UsePostgresbooltrueConfigure PostgreSQL as database
--UseSqlServerboolfalseConfigure SQL Server as database

Generated Structure

MyMinimalApi/
├── MyMinimalApi.csproj           # Project with Gryd.Core packages
├── Program.cs                     # Minimal startup configuration
├── appsettings.json              # Production configuration
├── appsettings.Development.json  # Development configuration
├── README.md                     # Project documentation
├── Controllers/
│   └── HelloController.cs        # Example controller
└── Data/
    └── AppDbContext.cs           # EF Core DbContext

Program.cs Example

csharp
var builder = WebApplication.CreateBuilder(args);

// Add Gryd Core
builder.Services.AddGrydCore();

// Add Database
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();

gryd-module

Clean Architecture module template. Creates a complete module structure following Domain-Driven Design principles, ready to be integrated into a host application.

Usage

bash
# Create with defaults (ModuleName=MyModule, with Tests and API)
dotnet new gryd-module -n Catalog

# Create with custom module name
dotnet new gryd-module -n Catalog --ModuleName Products

# Create without tests
dotnet new gryd-module -n Catalog --IncludeTests false

# Create without API layer (library only)
dotnet new gryd-module -n Catalog --IncludeApi false

Parameters

ParameterTypeDefaultDescription
--ModuleNamestringMyModuleName of the module (used in namespaces)
--IncludeTestsbooltrueInclude test project with xUnit
--IncludeApibooltrueInclude API layer with controllers

Generated Structure

Catalog/
├── Catalog.sln                          # Solution file
├── README.md                            # Module documentation

├── src/
│   ├── Catalog.Domain/                  # Domain Layer
│   │   ├── Catalog.Domain.csproj
│   │   ├── GlobalUsings.cs
│   │   ├── CatalogDomainAssemblyMarker.cs
│   │   └── Entities/
│   │       └── SampleEntity.cs          # Example aggregate root
│   │
│   ├── Catalog.Application/             # Application Layer
│   │   ├── Catalog.Application.csproj
│   │   ├── GlobalUsings.cs
│   │   ├── CatalogApplicationAssemblyMarker.cs
│   │   ├── DTOs/
│   │   │   └── SampleEntityDtos.cs      # DTOs for CRUD operations
│   │   └── Features/
│   │       └── SampleEntities/
│   │           ├── Commands/
│   │           │   └── SampleEntityCommands.cs  # Create, Update, Delete
│   │           ├── Queries/
│   │           │   └── SampleEntityQueries.cs   # GetById, GetPaged
│   │           └── Validators/
│   │               └── SampleEntityValidators.cs
│   │
│   ├── Catalog.Infrastructure/          # Infrastructure Layer
│   │   ├── Catalog.Infrastructure.csproj
│   │   ├── GlobalUsings.cs
│   │   ├── CatalogInfrastructureAssemblyMarker.cs
│   │   └── CatalogServiceCollectionExtensions.cs
│   │
│   └── Catalog.API/                     # API Layer (if IncludeApi=true)
│       ├── Catalog.API.csproj
│       ├── GlobalUsings.cs
│       ├── CatalogApiServiceCollectionExtensions.cs
│       └── Controllers/
│           └── SampleEntitiesController.cs

└── tests/                               # (if IncludeTests=true)
    └── Catalog.Tests/
        ├── Catalog.Tests.csproj
        ├── GlobalUsings.cs
        └── Domain/
            └── SampleEntityTests.cs     # Unit tests for domain

Layer Details

Domain Layer

Contains entities, value objects, and domain events. No external dependencies.

csharp
// Entities/SampleEntity.cs
public class SampleEntity : AggregateRoot
{
    public string Name { get; private set; } = string.Empty;
    public string? Description { get; private set; }
    public bool IsActive { get; private set; } = true;

    public static SampleEntity Create(string name, string? description = null)
    {
        Guard.NotNullOrWhiteSpace(name, nameof(name));
        
        var entity = new SampleEntity
        {
            Id = Guid.NewGuid(),
            Name = name,
            Description = description,
            IsActive = true
        };
        
        return entity;
    }

    public void Update(string name, string? description)
    {
        Guard.NotNullOrWhiteSpace(name, nameof(name));
        Name = name;
        Description = description;
    }

    public void Activate() => IsActive = true;
    public void Deactivate() => IsActive = false;
}

Application Layer

Contains DTOs, CQRS commands/queries, and validators.

csharp
// Features/SampleEntities/Commands/SampleEntityCommands.cs
public record CreateSampleEntityCommand(string Name, string? Description) 
    : ICommand<Result<SampleEntityDto>>;

public record UpdateSampleEntityCommand(Guid Id, string Name, string? Description) 
    : ICommand<Result<SampleEntityDto>>;

public record DeleteSampleEntityCommand(Guid Id) 
    : ICommand<Result>;

Infrastructure Layer

Contains service registration and external integrations.

csharp
// CatalogServiceCollectionExtensions.cs
public static class CatalogServiceCollectionExtensions
{
    public static IServiceCollection AddCatalog(this IServiceCollection services, IConfiguration configuration)
    {
        services.AddCatalogApplication();
        services.AddCatalogInfrastructure(configuration);
        return services;
    }
}

API Layer

Contains controllers that use MediatR to dispatch commands/queries.

csharp
// Controllers/SampleEntitiesController.cs
[ApiController]
[Route("api/[controller]")]
public class SampleEntitiesController : BaseController
{
    private readonly ISender _sender;

    [HttpGet]
    public async Task<IActionResult> GetAll([FromQuery] int page = 1, [FromQuery] int pageSize = 10)
    {
        var query = new GetSampleEntitiesQuery(page, pageSize);
        var result = await _sender.Send(query);
        return FromResult(result);
    }

    [HttpPost]
    public async Task<IActionResult> Create([FromBody] CreateSampleEntityDto dto)
    {
        var command = new CreateSampleEntityCommand(dto.Name, dto.Description);
        var result = await _sender.Send(command);
        return FromResult(result);
    }
}

Integration with Host Application

  1. Add project references to your host:
xml
<ProjectReference Include="path/to/Catalog.API/Catalog.API.csproj" />
<ProjectReference Include="path/to/Catalog.Infrastructure/Catalog.Infrastructure.csproj" />
  1. Register services in Program.cs:
csharp
// Add the module
builder.Services.AddCatalog(builder.Configuration);

// Add controllers from the module
builder.Services.AddControllers()
    .AddCatalogControllers();
  1. Configure the database context to include module entities:
csharp
public class AppDbContext : DbContext
{
    public DbSet<SampleEntity> SampleEntities => Set<SampleEntity>();
    
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfigurationsFromAssembly(
            typeof(CatalogInfrastructureAssemblyMarker).Assembly);
    }
}

Uninstalling Templates

To remove installed templates:

bash
dotnet new uninstall Gryd.IO.Templates

Or for locally installed:

bash
dotnet new uninstall ./templates/gryd-api
dotnet new uninstall ./templates/gryd-minimal
dotnet new uninstall ./templates/gryd-module

List Installed Templates

bash
dotnet new list gryd

Output:

Template Name    Short Name     Language  Tags
--------------   -----------    --------  ----
Gryd API         gryd-api       [C#]      Web/API/Gryd
Gryd Minimal     gryd-minimal   [C#]      Web/API/Gryd
Gryd Module      gryd-module    [C#]      Library/Gryd/Module

Database Setup

Prerequisites

Projects created with gryd-api or gryd-module (with --IncludeAuth true) require:

  • PostgreSQL (default) or SQL Server
  • Redis (for caching and token management)

Step 1: Start Infrastructure with Docker Compose

Each template includes a docker-compose.yml that starts the required databases:

bash
# Navigate to your project folder
cd MyProject

# Start PostgreSQL and Redis containers
docker-compose up -d

TIP

The docker-compose only starts the database services. Run your API locally with dotnet run for development.

Step 2: GrydAuth Migrations (Automatic in Development)

In Development environment, GrydAuth migrations are applied automatically when the application starts. Just run your application and the database schema will be created.

bash
# Navigate to your API project folder
cd src/MyProject.API

# Run the application (migrations are applied automatically)
dotnet run

Automatic Migrations

The template includes await app.ApplyGrydAuthMigrationsAsync() in the startup code, which automatically applies pending migrations when running in Development environment.

Production Environment

For production deployments, consider using a CI/CD pipeline or running migrations manually before deployment.

Step 3: Verify Database

After applying migrations, your database should have the following tables:

  • Users - User accounts
  • Roles - Role definitions
  • Permissions - Permission definitions
  • UserRoles - User-Role associations
  • RolePermissions - Role-Permission associations
  • UserPermissions - Direct user permissions
  • UserTenants - Multi-tenancy user associations
  • UserAppIds - Multi-app user registrations
  • RefreshTokens - JWT refresh tokens
  • FailedLoginAttempts - Brute-force protection
  • __EFMigrationsHistory - EF Core migrations tracking

Default Admin User

After applying migrations, a default admin user is seeded:

FieldValue
Emailadmin@gryd.io
PasswordAdmin@123
RoleAdmin

Security Warning

Change the default admin password immediately in production environments!

Step 3: Update Admin User AppId (Required)

After the first run, you must update the admin user's AppId to match the one generated in your appsettings.Development.json.

  1. Find the AppId in your appsettings.Development.json:
json
"JwtSettings": {
  "AppId": "MyProject-dev-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}
  1. Update the UserAppIds table in your database:
sql
-- Replace with your actual AppId from appsettings.Development.json
UPDATE public."UserAppIds"
SET "AppId" = 'MyProject-dev-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
WHERE "UserId" = '11111111-1111-1111-1111-111111111111';

Important

Without this update, login will fail with the error: Invalid application ID. The AppId in the token request must match the one registered for the user.


Quick Start Examples

Example 1: Create a Complete API Project

bash
# 1. Install templates
dotnet new install Gryd.IO.Templates

# 2. Create project with Auth + Crud
dotnet new gryd-api -n MyStore --IncludeAuth true --IncludeCrud true

# 3. Navigate to project
cd MyStore

# 4. Start databases
docker-compose up -d

# 5. Run the application (migrations are applied automatically)
cd src/MyStore.API
dotnet run

# 6. Update admin AppId (first run only)
# Get AppId from appsettings.Development.json and update UserAppIds table:
# UPDATE public."UserAppIds" SET "AppId" = 'your-appid' WHERE "UserId" = '11111111-1111-1111-1111-111111111111';

# 7. Access Swagger UI
# Open: http://localhost:5000/swagger

Example 2: Create a Module and Add to Existing Project

bash
# 1. Create a new module
dotnet new gryd-module -n Inventory --IncludeAuth true

# 2. Add module references to your host project
# (add to your .csproj)

# 3. Register in Program.cs:
# builder.Services.AddInventoryServices(builder.Configuration);

# 4. Start databases
docker-compose up -d

# 5. Run the application (migrations are applied automatically)
dotnet run

# 6. Update admin AppId in database (see Database Setup section)

Example 3: Create a Minimal API (No Auth)

bash
# 1. Create minimal project
dotnet new gryd-minimal -n MyMicroservice

# 2. Navigate to project
cd MyMicroservice

# 3. Run (no migrations needed - no GrydAuth)
dotnet run

Troubleshooting

Database does not exist

If you see database "xxx" does not exist:

bash
# Remove volumes and recreate
docker-compose down -v
docker-compose up -d

Invalid application ID

If login fails with Invalid application ID, update the admin user's AppId:

sql
UPDATE public."UserAppIds"
SET "AppId" = 'your-appid-from-appsettings'
WHERE "UserId" = '11111111-1111-1111-1111-111111111111';

NuGet cache issues

If packages are not updating:

bash
# Clear NuGet cache
dotnet nuget locals all --clear

# Restore packages
dotnet restore --force

Port already in use

If port 5000 is in use (common on macOS with AirPlay):

  1. Find the process: lsof -i :5000
  2. Kill it: kill -9 <PID>
  3. Or disable AirPlay Receiver in System Settings

Released under the MIT License.