Files
Manuel de la Peña b951e92f57 feat(guides): migrate all testcontainers.com guides (#24505)
## Description

Migrate 17 Testcontainers guides from testcontainers.com into the Docker
docs site, covering Java (14 guides), .NET (2 guides), and Node.js (1
guide). This follows up on PR #24450 which added the initial Go and
Python guides.

Each guide is converted from AsciiDoc to Hugo Markdown, split into
multi-chapter stepper navigation, updated to the latest Testcontainers
API, and verified with passing tests running in containers.

Java guides use testcontainers-java 2.0.4 with the new 2.x Maven
coordinates and package names (e.g., `testcontainers-postgresql`,
`org.testcontainers.postgresql.PostgreSQLContainer`). The Quarkus guide
uses Quarkus 3.22.3 with TC 1.x managed by the Quarkus BOM, since no
released Quarkus version ships TC 2.x yet.

## How to test

All code snippets have been verified by running each guide's source
repository tests inside Docker containers with the Docker socket
mounted.

To re-run the verification, use the `/testcontainers-guides-migrator`
skill included in this PR
(`.claude/skills/testcontainers-guides-migrator/SKILL.md`). The skill's
Step 6 documents the exact container commands and macOS Docker Desktop
workarounds (host override, docker-java API version, etc.) needed to run
each language's tests:

```
/testcontainers-guides-migrator I want you to verify all the guides in this branch.
Do a full review, verifying that all code snippets compile, the code is executable,
and ALL the tests pass. Run them as docker containers, never locally.
```

## Related issues or tickets

Supersedes #24450 (expanded from 2 guides to all 19)

## Reviews

- [ ] Technical review
- [ ] Editorial review
- [ ] Product review

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 10:03:26 +00:00

3.6 KiB

title, linkTitle, description, weight
title linkTitle description weight
Create the .NET project Create the project Set up a .NET solution with a PostgreSQL-backed customer service. 10

Set up the solution

Create a .NET solution with source and test projects:

$ dotnet new sln -o TestcontainersDemo
$ cd TestcontainersDemo
$ dotnet new classlib -o CustomerService
$ dotnet sln add ./CustomerService/CustomerService.csproj
$ dotnet new xunit -o CustomerService.Tests
$ dotnet sln add ./CustomerService.Tests/CustomerService.Tests.csproj
$ dotnet add ./CustomerService.Tests/CustomerService.Tests.csproj reference ./CustomerService/CustomerService.csproj

Add the Npgsql dependency to the source project:

$ dotnet add ./CustomerService/CustomerService.csproj package Npgsql

Implement the business logic

Create a Customer record type:

namespace Customers;

public readonly record struct Customer(long Id, string Name);

Create a DbConnectionProvider class to manage database connections:

using System.Data.Common;
using Npgsql;

namespace Customers;

public sealed class DbConnectionProvider
{
    private readonly string _connectionString;

    public DbConnectionProvider(string connectionString)
    {
        _connectionString = connectionString;
    }

    public DbConnection GetConnection()
    {
        return new NpgsqlConnection(_connectionString);
    }
}

Create the CustomerService class:

namespace Customers;

public sealed class CustomerService
{
    private readonly DbConnectionProvider _dbConnectionProvider;

    public CustomerService(DbConnectionProvider dbConnectionProvider)
    {
        _dbConnectionProvider = dbConnectionProvider;
        CreateCustomersTable();
    }

    public IEnumerable<Customer> GetCustomers()
    {
        IList<Customer> customers = new List<Customer>();

        using var connection = _dbConnectionProvider.GetConnection();
        using var command = connection.CreateCommand();
        command.CommandText = "SELECT id, name FROM customers";
        command.Connection?.Open();

        using var dataReader = command.ExecuteReader();
        while (dataReader.Read())
        {
            var id = dataReader.GetInt64(0);
            var name = dataReader.GetString(1);
            customers.Add(new Customer(id, name));
        }

        return customers;
    }

    public void Create(Customer customer)
    {
        using var connection = _dbConnectionProvider.GetConnection();
        using var command = connection.CreateCommand();

        var id = command.CreateParameter();
        id.ParameterName = "@id";
        id.Value = customer.Id;

        var name = command.CreateParameter();
        name.ParameterName = "@name";
        name.Value = customer.Name;

        command.CommandText = "INSERT INTO customers (id, name) VALUES(@id, @name)";
        command.Parameters.Add(id);
        command.Parameters.Add(name);
        command.Connection?.Open();
        command.ExecuteNonQuery();
    }

    private void CreateCustomersTable()
    {
        using var connection = _dbConnectionProvider.GetConnection();
        using var command = connection.CreateCommand();
        command.CommandText = "CREATE TABLE IF NOT EXISTS customers (id BIGINT NOT NULL, name VARCHAR NOT NULL, PRIMARY KEY (id))";
        command.Connection?.Open();
        command.ExecuteNonQuery();
    }
}

Here's what CustomerService does:

  • The constructor calls CreateCustomersTable() to ensure the table exists.
  • GetCustomers() fetches all rows from the customers table and returns them as Customer objects.
  • Create() inserts a customer record into the database.