steering_docs/dotnet-tech.md
# Build and Package
dotnet build SOLUTION.sln # Build solution
dotnet build PROJECT.csproj # Build specific project
dotnet clean # Clean build artifacts
# Testing
dotnet test # Run all tests
dotnet test --filter Category=Integration # Run integration tests
dotnet test --logger trx # Run tests with detailed output
# Execution
dotnet run # Run project
dotnet run --project PROJECT.csproj # Run specific project
# Code Quality
dotnet format # Format code
{Service}Actions.cs (e.g., S3Actions.cs)Hello{Service}.cs (e.g., HelloS3.cs){Service}Tests.csHello{Service}.cs class with main methodnamespace RedshiftActions;)Async (e.g., ListBucketsAsync)<TargetFramework>net8.0</TargetFramework>)<LangVersion>latest</LangVersion>)[{Service}.dotnetv4.{ActionName}] (e.g., [Redshift.dotnetv4.CreateCluster]) /// <summary>
/// Main entry point for the AWS Control Tower basics scenario.
/// </summary>
/// <param name="args">Command line arguments.</param>
public static async Task Main(string[] args)
{
using var host = Host.CreateDefaultBuilder(args)
.ConfigureServices((_, services) =>
services.AddAWSService<IAmazonControlTower>()
.AddAWSService<IAmazonControlCatalog>()
.AddAWSService<IAmazonOrganizations>()
.AddAWSService<IAmazonSecurityTokenService>()
.AddTransient<ControlTowerWrapper>()
)
.Build();
logger = LoggerFactory.Create(builder => { builder.AddConsole(); })
.CreateLogger<ControlTowerBasics>();
wrapper = host.Services.GetRequiredService<ControlTowerWrapper>();
orgClient = host.Services.GetRequiredService<IAmazonOrganizations>();
stsClient = host.Services.GetRequiredService<IAmazonSecurityTokenService>();
await RunScenario();
}
using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.Threading.Tasks;
public class ExampleClass
{
public async Task ExampleMethodAsync()
{
var s3Client = new AmazonS3Client();
try
{
var response = await s3Client.ListBucketsAsync();
// Process response
Console.WriteLine($"Found {response.Buckets.Count} buckets");
}
catch (AmazonS3Exception e)
{
// Handle S3-specific exceptions
Console.WriteLine($"S3 Error: {e.Message}");
Console.WriteLine($"Error Code: {e.ErrorCode}");
throw;
}
catch (Exception e)
{
// Handle general exceptions
Console.WriteLine($"Error: {e.Message}");
throw;
}
finally
{
s3Client?.Dispose();
}
}
}
[Fact], [Theory])[Trait("Category", "Integration")]async Task for async test methodsusing statements for AWS clientsdotnetv4/{Service}/
├── Actions/
│ ├── Hello{Service}.cs # Hello example (with Main method)
│ ├── {Service}Wrapper.cs # Service wrapper class
│ └── {Service}Actions.csproj # Actions project file
├── Scenarios/
│ ├── {Service}Basics.cs # Basics scenario
│ └── {Service}Basics.csproj # Scenarios project file
├── Tests/
│ ├── {Service}IntegrationTests.cs # Integration tests only
│ └── {Service}Tests.csproj # Test project file
└── {Service}Examples.sln # Service-specific solution file
CRITICAL Project Organization Rules:
/// for class and method documentation<param><returns><exception>aws sts get-caller-identitylistDirectory to find the correct project/solution file path before trying to build again<TargetFramework>net8.0</TargetFramework>)<LangVersion>latest</LangVersion>)<Nullable>enable</Nullable>)Each service should have its own solution file in the service directory:
# Create solution file
dotnet new sln -n {Service}Examples -o dotnetv4/{Service}
# Add projects to solution
dotnet sln dotnetv4/{Service}/{Service}Examples.sln add dotnetv4/{Service}/Actions/{Service}Actions.csproj
dotnet sln dotnetv4/{Service}/{Service}Examples.sln add dotnetv4/{Service}/Scenarios/{Service}Basics.csproj
dotnet sln dotnetv4/{Service}/{Service}Examples.sln add dotnetv4/{Service}/Tests/{Service}Tests.csproj
# Build solution
dotnet build dotnetv4/{Service}/{Service}Examples.sln
Solution Structure:
Before creating .NET code examples:
coding-standards-KB for "DotNet-code-example-standards"DotNet-premium-KB for "DotNet implementation patterns"