Appearance
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.TemplatesFrom 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-moduleVerify Installation
List all installed Gryd templates:
bash
dotnet new list grydExpected 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/ModuleAvailable Templates
| Template | Short Name | Description |
|---|---|---|
| Gryd API | gryd-api | Complete API with Auth + Crud modules |
| Gryd Minimal | gryd-minimal | Minimal API with Core packages only |
| Gryd Module | gryd-module | Clean 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 falseParameters
| Parameter | Type | Default | Description |
|---|---|---|---|
--IncludeAuth | bool | true | Include GrydAuth for authentication/authorization |
--IncludeCrud | bool | true | Include GrydCrud for CRUD operations |
--UsePostgres | bool | true | Configure PostgreSQL as database |
--UseSqlServer | bool | false | Configure SQL Server as database |
--IncludeDocker | bool | true | Include 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 trueParameters
| Parameter | Type | Default | Description |
|---|---|---|---|
--UsePostgres | bool | true | Configure PostgreSQL as database |
--UseSqlServer | bool | false | Configure 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 DbContextProgram.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 falseParameters
| Parameter | Type | Default | Description |
|---|---|---|---|
--ModuleName | string | MyModule | Name of the module (used in namespaces) |
--IncludeTests | bool | true | Include test project with xUnit |
--IncludeApi | bool | true | Include 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 domainLayer 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
- 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" />- Register services in Program.cs:
csharp
// Add the module
builder.Services.AddCatalog(builder.Configuration);
// Add controllers from the module
builder.Services.AddControllers()
.AddCatalogControllers();- 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.TemplatesOr for locally installed:
bash
dotnet new uninstall ./templates/gryd-api
dotnet new uninstall ./templates/gryd-minimal
dotnet new uninstall ./templates/gryd-moduleList Installed Templates
bash
dotnet new list grydOutput:
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/ModuleDatabase 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 -dTIP
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 runAutomatic 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 accountsRoles- Role definitionsPermissions- Permission definitionsUserRoles- User-Role associationsRolePermissions- Role-Permission associationsUserPermissions- Direct user permissionsUserTenants- Multi-tenancy user associationsUserAppIds- Multi-app user registrationsRefreshTokens- JWT refresh tokensFailedLoginAttempts- Brute-force protection__EFMigrationsHistory- EF Core migrations tracking
Default Admin User
After applying migrations, a default admin user is seeded:
| Field | Value |
|---|---|
admin@gryd.io | |
| Password | Admin@123 |
| Role | Admin |
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.
- Find the
AppIdin yourappsettings.Development.json:
json
"JwtSettings": {
"AppId": "MyProject-dev-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}- Update the
UserAppIdstable 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/swaggerExample 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 runTroubleshooting
Database does not exist
If you see database "xxx" does not exist:
bash
# Remove volumes and recreate
docker-compose down -v
docker-compose up -dInvalid 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 --forcePort already in use
If port 5000 is in use (common on macOS with AirPlay):
- Find the process:
lsof -i :5000 - Kill it:
kill -9 <PID> - Or disable AirPlay Receiver in System Settings