From 607ff3831c429fc27664dc0f40aae257328f0d9b Mon Sep 17 00:00:00 2001 From: David Pine Date: Tue, 5 Dec 2023 08:17:04 -0600 Subject: [PATCH 1/7] Initial bits --- docs/components-overview.md | 26 ++-- .../AspireApp.AppHost.csproj | 19 +++ .../AspireApp/AspireApp.AppHost/Program.cs | 10 ++ .../Properties/launchSettings.json | 16 +++ .../appsettings.Development.json | 8 ++ .../AspireApp.AppHost/appsettings.json | 9 ++ .../AspireApp.ServiceDefaults.csproj | 24 ++++ .../AspireApp.ServiceDefaults/Extensions.cs | 119 ++++++++++++++++++ .../components/AspireApp/AspireApp.sln | 36 ++++++ .../AspireApp/WorkerService/Program.cs | 11 ++ .../Properties/launchSettings.json | 12 ++ .../AspireApp/WorkerService/Worker.cs | 18 +++ .../WorkerService/WorkerService.csproj | 18 +++ .../appsettings.Development.json | 8 ++ .../AspireApp/WorkerService/appsettings.json | 8 ++ 15 files changed, 334 insertions(+), 8 deletions(-) create mode 100644 docs/snippets/components/AspireApp/AspireApp.AppHost/AspireApp.AppHost.csproj create mode 100644 docs/snippets/components/AspireApp/AspireApp.AppHost/Program.cs create mode 100644 docs/snippets/components/AspireApp/AspireApp.AppHost/Properties/launchSettings.json create mode 100644 docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.Development.json create mode 100644 docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.json create mode 100644 docs/snippets/components/AspireApp/AspireApp.ServiceDefaults/AspireApp.ServiceDefaults.csproj create mode 100644 docs/snippets/components/AspireApp/AspireApp.ServiceDefaults/Extensions.cs create mode 100644 docs/snippets/components/AspireApp/AspireApp.sln create mode 100644 docs/snippets/components/AspireApp/WorkerService/Program.cs create mode 100644 docs/snippets/components/AspireApp/WorkerService/Properties/launchSettings.json create mode 100644 docs/snippets/components/AspireApp/WorkerService/Worker.cs create mode 100644 docs/snippets/components/AspireApp/WorkerService/WorkerService.csproj create mode 100644 docs/snippets/components/AspireApp/WorkerService/appsettings.Development.json create mode 100644 docs/snippets/components/AspireApp/WorkerService/appsettings.json diff --git a/docs/components-overview.md b/docs/components-overview.md index ac4275b00..8e61a6113 100644 --- a/docs/components-overview.md +++ b/docs/components-overview.md @@ -1,7 +1,7 @@ --- title: .NET Aspire components overview description: Explore the fundamental concepts of .NET Aspire components and learn how to integrate them into your apps. -ms.date: 12/03/2023 +ms.date: 12/05/2023 ms.topic: conceptual --- @@ -35,7 +35,7 @@ The following table lists the .NET Aspire components currently available for use ## Explore a sample component workflow -.NET Aspire components streamline the process of consuming popular services and platforms. For example, you could use the .NET Aspire PostgreSQL component to connect to and utilize a PostgreSQL database. The database could be hosted on-prem or in a cloud service such as Azure, AWS, or GCP. The following steps demonstrate how to integrate this component into your app: +.NET Aspire components streamline the process of consuming popular services and platforms. For example, you could use the [.NET Aspire PostgreSQL component](database/postgresql-component.md) to connect to and utilize a PostgreSQL database. The database could be hosted on-prem or in a cloud service such as Azure, AWS, or GCP. The following steps demonstrate how to integrate this component into your app: 1. Install the [Aspire.Npgsql](https://www.nuget.org/packages/Aspire.Npgsql) NuGet package. @@ -56,14 +56,24 @@ The following table lists the .NET Aspire components currently available for use For more information, see [dotnet add package](/dotnet/core/tools/dotnet-add-package) or [Manage package dependencies in .NET applications](/dotnet/core/tools/dependencies). -1. In the _Program.cs_ file of your project, call the extension method to register a `NpgsqlDataSource` for use via the dependency injection container. The method expects a connection name parameter. +1. In the _Program.cs_ file of your component consuming project, call the extension method to register a `NpgsqlDataSource` for use via the dependency injection container. The method expects a connection name parameter. Consider the following [Worker Service](/dotnet/core/extensions/workers) example: - ```csharp - builder.AddNpgsqlDataSource("PostgreSqlConnection"); - ``` + :::code source="snippets/components/AspireApp/WorkerService/Program.cs" highlight="5"::: + + The preceding code adds the `NpgsqlDataSource` to the dependency injection container with the name `PostgreSqlConnection`. + + > [!TIP] + > Components that are designed to connect to Azure services also support passwordless authentication and authorization using [Azure RBAC](/azure/role-based-access-control/overview), which is the recommended approach for production apps. + +1. In your orchestrator project (the project with the _*.AppHost_ suffix), add a reference to the component consuming project. If you're using Visual Studio, you can use the **Add .NET Aspire Orchestrator Support** project context menu item to add the reference automatically. The following code snippet shows the reference added to the _AspireApp.AppHost.csproj_ file: + + :::code language="xml" source="snippets/components/AspireApp/AspireApp.AppHost/AspireApp.AppHost.csproj" highlight="16"::: + + For more information about AppHost tooling features, see [Add .NET Aspire Orchestrator Support](setup-tooling.md#add-orchestration-projects). + + After the project is referenced in the orchestrator project, the component consuming project has its _Program.cs_ file updated to call the `AddServiceDefaults`. For more information about the service defaults project and its purpose, see [.NET Aspire service defaults](service-defaults.md). - > [!NOTE] - > Components that are designed to connect to Azure services also support passwordless authentication and authorization using Azure RBAC, which is the recommended approach for production apps. +1. TODO: show the app host _Program.cs_ file 1. Add a connection string with a matching name in your _appsettings.json_ file. diff --git a/docs/snippets/components/AspireApp/AspireApp.AppHost/AspireApp.AppHost.csproj b/docs/snippets/components/AspireApp/AspireApp.AppHost/AspireApp.AppHost.csproj new file mode 100644 index 000000000..7a8f6eac7 --- /dev/null +++ b/docs/snippets/components/AspireApp/AspireApp.AppHost/AspireApp.AppHost.csproj @@ -0,0 +1,19 @@ + + + + Exe + net8.0 + enable + enable + true + + + + + + + + + + + diff --git a/docs/snippets/components/AspireApp/AspireApp.AppHost/Program.cs b/docs/snippets/components/AspireApp/AspireApp.AppHost/Program.cs new file mode 100644 index 000000000..764311f27 --- /dev/null +++ b/docs/snippets/components/AspireApp/AspireApp.AppHost/Program.cs @@ -0,0 +1,10 @@ +var builder = DistributedApplication.CreateBuilder(args); + +var database = builder.AddPostgresContainer("PostgreSqlConnection") + .AddDatabase("dbname"); + +builder.AddProject("workerservice") + .WithReference(database) + .WithReplicas(5); + +builder.Build().Run(); diff --git a/docs/snippets/components/AspireApp/AspireApp.AppHost/Properties/launchSettings.json b/docs/snippets/components/AspireApp/AspireApp.AppHost/Properties/launchSettings.json new file mode 100644 index 000000000..3694cf70b --- /dev/null +++ b/docs/snippets/components/AspireApp/AspireApp.AppHost/Properties/launchSettings.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:15021", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16244" + } + } + } +} diff --git a/docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.Development.json b/docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.Development.json new file mode 100644 index 000000000..0c208ae91 --- /dev/null +++ b/docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.json b/docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.json new file mode 100644 index 000000000..31c092aa4 --- /dev/null +++ b/docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "Aspire.Hosting.Dcp": "Warning" + } + } +} diff --git a/docs/snippets/components/AspireApp/AspireApp.ServiceDefaults/AspireApp.ServiceDefaults.csproj b/docs/snippets/components/AspireApp/AspireApp.ServiceDefaults/AspireApp.ServiceDefaults.csproj new file mode 100644 index 000000000..00e0d1f1f --- /dev/null +++ b/docs/snippets/components/AspireApp/AspireApp.ServiceDefaults/AspireApp.ServiceDefaults.csproj @@ -0,0 +1,24 @@ + + + + Library + net8.0 + enable + enable + true + + + + + + + + + + + + + + + + diff --git a/docs/snippets/components/AspireApp/AspireApp.ServiceDefaults/Extensions.cs b/docs/snippets/components/AspireApp/AspireApp.ServiceDefaults/Extensions.cs new file mode 100644 index 000000000..c59308d50 --- /dev/null +++ b/docs/snippets/components/AspireApp/AspireApp.ServiceDefaults/Extensions.cs @@ -0,0 +1,119 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Logs; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; + +namespace Microsoft.Extensions.Hosting; + +public static class Extensions +{ + public static IHostApplicationBuilder AddServiceDefaults(this IHostApplicationBuilder builder) + { + builder.ConfigureOpenTelemetry(); + + builder.AddDefaultHealthChecks(); + + builder.Services.AddServiceDiscovery(); + + builder.Services.ConfigureHttpClientDefaults(http => + { + // Turn on resilience by default + http.AddStandardResilienceHandler(); + + // Turn on service discovery by default + http.UseServiceDiscovery(); + }); + + return builder; + } + + public static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicationBuilder builder) + { + builder.Logging.AddOpenTelemetry(logging => + { + logging.IncludeFormattedMessage = true; + logging.IncludeScopes = true; + }); + + builder.Services.AddOpenTelemetry() + .WithMetrics(metrics => + { + metrics.AddRuntimeInstrumentation() + .AddBuiltInMeters(); + }) + .WithTracing(tracing => + { + if (builder.Environment.IsDevelopment()) + { + // We want to view all traces in development + tracing.SetSampler(new AlwaysOnSampler()); + } + + tracing.AddAspNetCoreInstrumentation() + .AddGrpcClientInstrumentation() + .AddHttpClientInstrumentation(); + }); + + builder.AddOpenTelemetryExporters(); + + return builder; + } + + private static IHostApplicationBuilder AddOpenTelemetryExporters(this IHostApplicationBuilder builder) + { + var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]); + + if (useOtlpExporter) + { + builder.Services.Configure(logging => logging.AddOtlpExporter()); + builder.Services.ConfigureOpenTelemetryMeterProvider(metrics => metrics.AddOtlpExporter()); + builder.Services.ConfigureOpenTelemetryTracerProvider(tracing => tracing.AddOtlpExporter()); + } + + // Uncomment the following lines to enable the Prometheus exporter (requires the OpenTelemetry.Exporter.Prometheus.AspNetCore package) + // builder.Services.AddOpenTelemetry() + // .WithMetrics(metrics => metrics.AddPrometheusExporter()); + + // Uncomment the following lines to enable the Azure Monitor exporter (requires the Azure.Monitor.OpenTelemetry.Exporter package) + // builder.Services.AddOpenTelemetry() + // .UseAzureMonitor(); + + return builder; + } + + public static IHostApplicationBuilder AddDefaultHealthChecks(this IHostApplicationBuilder builder) + { + builder.Services.AddHealthChecks() + // Add a default liveness check to ensure app is responsive + .AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]); + + return builder; + } + + public static WebApplication MapDefaultEndpoints(this WebApplication app) + { + // Uncomment the following line to enable the Prometheus endpoint (requires the OpenTelemetry.Exporter.Prometheus.AspNetCore package) + // app.MapPrometheusScrapingEndpoint(); + + // All health checks must pass for app to be considered ready to accept traffic after starting + app.MapHealthChecks("/health"); + + // Only health checks tagged with the "live" tag must pass for app to be considered alive + app.MapHealthChecks("/alive", new HealthCheckOptions + { + Predicate = r => r.Tags.Contains("live") + }); + + return app; + } + + private static MeterProviderBuilder AddBuiltInMeters(this MeterProviderBuilder meterProviderBuilder) => + meterProviderBuilder.AddMeter( + "Microsoft.AspNetCore.Hosting", + "Microsoft.AspNetCore.Server.Kestrel", + "System.Net.Http"); +} diff --git a/docs/snippets/components/AspireApp/AspireApp.sln b/docs/snippets/components/AspireApp/AspireApp.sln new file mode 100644 index 000000000..f359e57a0 --- /dev/null +++ b/docs/snippets/components/AspireApp/AspireApp.sln @@ -0,0 +1,36 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34310.174 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.AppHost", "AspireApp.AppHost\AspireApp.AppHost.csproj", "{5ECB1120-CA00-4E6B-B58B-119AC1BD7EAB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspireApp.ServiceDefaults", "AspireApp.ServiceDefaults\AspireApp.ServiceDefaults.csproj", "{D70B1822-D354-41BC-932F-F38A390E1A95}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WorkerService", "WorkerService\WorkerService.csproj", "{31496392-228C-4C0C-97FC-A311A82723CB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5ECB1120-CA00-4E6B-B58B-119AC1BD7EAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5ECB1120-CA00-4E6B-B58B-119AC1BD7EAB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5ECB1120-CA00-4E6B-B58B-119AC1BD7EAB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5ECB1120-CA00-4E6B-B58B-119AC1BD7EAB}.Release|Any CPU.Build.0 = Release|Any CPU + {D70B1822-D354-41BC-932F-F38A390E1A95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D70B1822-D354-41BC-932F-F38A390E1A95}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D70B1822-D354-41BC-932F-F38A390E1A95}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D70B1822-D354-41BC-932F-F38A390E1A95}.Release|Any CPU.Build.0 = Release|Any CPU + {31496392-228C-4C0C-97FC-A311A82723CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {31496392-228C-4C0C-97FC-A311A82723CB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {31496392-228C-4C0C-97FC-A311A82723CB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {31496392-228C-4C0C-97FC-A311A82723CB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {77615A82-474F-4434-B928-5CF7A56A09C7} + EndGlobalSection +EndGlobal diff --git a/docs/snippets/components/AspireApp/WorkerService/Program.cs b/docs/snippets/components/AspireApp/WorkerService/Program.cs new file mode 100644 index 000000000..edadfa3a0 --- /dev/null +++ b/docs/snippets/components/AspireApp/WorkerService/Program.cs @@ -0,0 +1,11 @@ +using WorkerService; + +var builder = Host.CreateApplicationBuilder(args); + +builder.AddNpgsqlDataSource("PostgreSqlConnection"); + +builder.AddServiceDefaults(); +builder.Services.AddHostedService(); + +var host = builder.Build(); +host.Run(); diff --git a/docs/snippets/components/AspireApp/WorkerService/Properties/launchSettings.json b/docs/snippets/components/AspireApp/WorkerService/Properties/launchSettings.json new file mode 100644 index 000000000..1db52499c --- /dev/null +++ b/docs/snippets/components/AspireApp/WorkerService/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "WorkerService": { + "commandName": "Project", + "dotnetRunMessages": true, + "environmentVariables": { + "DOTNET_ENVIRONMENT": "Development" + } + } + } +} diff --git a/docs/snippets/components/AspireApp/WorkerService/Worker.cs b/docs/snippets/components/AspireApp/WorkerService/Worker.cs new file mode 100644 index 000000000..f79cc6abc --- /dev/null +++ b/docs/snippets/components/AspireApp/WorkerService/Worker.cs @@ -0,0 +1,18 @@ +using Npgsql; + +namespace WorkerService; + +public sealed class Worker( + ILogger logger, + NpgsqlDataSource dataSource) : BackgroundService +{ + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + while (!stoppingToken.IsCancellationRequested) + { + // Use the dataSource + + await Task.Delay(1_000, stoppingToken); + } + } +} diff --git a/docs/snippets/components/AspireApp/WorkerService/WorkerService.csproj b/docs/snippets/components/AspireApp/WorkerService/WorkerService.csproj new file mode 100644 index 000000000..944adf4f8 --- /dev/null +++ b/docs/snippets/components/AspireApp/WorkerService/WorkerService.csproj @@ -0,0 +1,18 @@ + + + + net8.0 + enable + enable + dotnet-WorkerService-9b27f862-501e-46ec-982c-ad843ccf73a8 + + + + + + + + + + + diff --git a/docs/snippets/components/AspireApp/WorkerService/appsettings.Development.json b/docs/snippets/components/AspireApp/WorkerService/appsettings.Development.json new file mode 100644 index 000000000..b2dcdb674 --- /dev/null +++ b/docs/snippets/components/AspireApp/WorkerService/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/docs/snippets/components/AspireApp/WorkerService/appsettings.json b/docs/snippets/components/AspireApp/WorkerService/appsettings.json new file mode 100644 index 000000000..b2dcdb674 --- /dev/null +++ b/docs/snippets/components/AspireApp/WorkerService/appsettings.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} From 80da0d0034724faf1e792c356fb99791d2a86eeb Mon Sep 17 00:00:00 2001 From: David Pine Date: Tue, 5 Dec 2023 09:38:17 -0600 Subject: [PATCH 2/7] More example updates --- docs/app-host-overview.md | 4 +- docs/components-overview.md | 43 +++++++++++-------- .../AspireApp/AspireApp.AppHost/Program.cs | 9 ++-- .../appsettings.Development.json | 13 +++--- .../AspireApp.AppHost/appsettings.json | 12 +++--- .../AspireApp/WorkerService/Worker.cs | 2 +- 6 files changed, 48 insertions(+), 35 deletions(-) diff --git a/docs/app-host-overview.md b/docs/app-host-overview.md index e78febfa3..d6fd4a8e1 100644 --- a/docs/app-host-overview.md +++ b/docs/app-host-overview.md @@ -1,7 +1,7 @@ --- title: .NET Aspire orchestration overview description: Learn the fundamental concepts of .NET Aspire orchestration and explore the various APIs to express resource references. -ms.date: 11/15/2023 +ms.date: 12/05/2023 ms.topic: overview --- @@ -11,7 +11,7 @@ ms.topic: overview Before continuing, consider some common terminology used in .NET Aspire: -- **App model**: A collection of resources that make up your distributed application (`DistributedApplication`). For a more formal definition, see [Define the app model](#define-the-app-model). +- **App model**: A collection of resources that make up your distributed application (). For a more formal definition, see [Define the app model](#define-the-app-model). - **App host/Orchestrator project**: The .NET project that orchestrates the _app model_, named with the _*.AppHost_ suffix (by convention). - **Resource**: A [resource](#built-in-resource-types) represents a part of an application whether it be a .NET project, container, or executable, or some other resource like a database, cache, or cloud service (such as a storage service). - **Reference**: A reference defines a connection between resources, expressed as a dependency. For more information, see [Reference resources](#reference-resources). diff --git a/docs/components-overview.md b/docs/components-overview.md index 8e61a6113..aab15067a 100644 --- a/docs/components-overview.md +++ b/docs/components-overview.md @@ -7,9 +7,7 @@ ms.topic: conceptual # .NET Aspire components overview -.NET Aspire components are a curated suite of NuGet packages specifically selected to facilitate the integration of cloud-native applications with prominent services and platforms, including but not limited to Redis and PostgreSQL. Each component furnishes essential cloud-native functionalities through either automatic provisioning or standardized configuration patterns. - -For more information on working with .NET Aspire components in Visual Studio, see [Visual Studio tooling](setup-tooling.md#visual-studio-tooling). +.NET Aspire components are a curated suite of NuGet packages specifically selected to facilitate the integration of cloud-native applications with prominent services and platforms, including but not limited to Redis and PostgreSQL. Each component furnishes essential cloud-native functionalities through either automatic provisioning or standardized configuration patterns. .NET Aspire components can be used without an orchestrator project, but they're designed to work best with the [.NET Aspire app host](app-host-overview.md). ## Available components @@ -33,11 +31,13 @@ The following table lists the .NET Aspire components currently available for use | [SQL Server Entity Framework Core](database/sql-server-entity-framework-component.md) | [Aspire.Microsoft.EntityFrameworkCore.SqlServer](https://www.nuget.org/packages/Aspire.Microsoft.EntityFrameworkCore.SqlServer) | A library for accessing [SQL Server databases using Entity Framework Core](/ef/core/providers/sql-server/). | | [SQL Server](database/sql-server-component.md) | [Aspire.Microsoft.Data.SqlClient](https://www.nuget.org/packages/Aspire.Microsoft.Data.SqlClient) | A library for accessing [SQL Server](/sql/sql-server/) databases. | +For more information on working with .NET Aspire components in Visual Studio, see [Visual Studio tooling](setup-tooling.md#visual-studio-tooling). + ## Explore a sample component workflow -.NET Aspire components streamline the process of consuming popular services and platforms. For example, you could use the [.NET Aspire PostgreSQL component](database/postgresql-component.md) to connect to and utilize a PostgreSQL database. The database could be hosted on-prem or in a cloud service such as Azure, AWS, or GCP. The following steps demonstrate how to integrate this component into your app: +.NET Aspire components streamline the process of consuming popular services and platforms. For example, consider the **.NET Aspire Application** template. With this template, you get the [AppHost](app-host-overview.md) and [ServiceDefaults](service-defaults.md) projects. Imagine that you have a need for a Worker Service project to perform some database processing. You could use the [.NET Aspire PostgreSQL component](database/postgresql-component.md) to connect to and utilize a PostgreSQL database. The database could be hosted on-prem or in a cloud service such as Azure, AWS, or GCP. The following steps demonstrate how to integrate this component into your app: -1. Install the [Aspire.Npgsql](https://www.nuget.org/packages/Aspire.Npgsql) NuGet package. +1. In the component consuming (Worker Service) project, install the [Aspire.Npgsql](https://www.nuget.org/packages/Aspire.Npgsql) NuGet package. # [.NET CLI](#tab/dotnet-cli) @@ -56,26 +56,37 @@ The following table lists the .NET Aspire components currently available for use For more information, see [dotnet add package](/dotnet/core/tools/dotnet-add-package) or [Manage package dependencies in .NET applications](/dotnet/core/tools/dependencies). -1. In the _Program.cs_ file of your component consuming project, call the extension method to register a `NpgsqlDataSource` for use via the dependency injection container. The method expects a connection name parameter. Consider the following [Worker Service](/dotnet/core/extensions/workers) example: +1. In the _Program.cs_ file of your Worker Service project, call the extension method to register a `NpgsqlDataSource` for use via the dependency injection container. The method expects a connection name parameter. :::code source="snippets/components/AspireApp/WorkerService/Program.cs" highlight="5"::: - The preceding code adds the `NpgsqlDataSource` to the dependency injection container with the name `PostgreSqlConnection`. + The preceding code adds the `NpgsqlDataSource` to the dependency injection container with the connection name of `"PostgreSqlConnection"`. The connection name is later used by the orchestrator project, when expressing resource dependencies. > [!TIP] > Components that are designed to connect to Azure services also support passwordless authentication and authorization using [Azure RBAC](/azure/role-based-access-control/overview), which is the recommended approach for production apps. -1. In your orchestrator project (the project with the _*.AppHost_ suffix), add a reference to the component consuming project. If you're using Visual Studio, you can use the **Add .NET Aspire Orchestrator Support** project context menu item to add the reference automatically. The following code snippet shows the reference added to the _AspireApp.AppHost.csproj_ file: +1. In your orchestrator project (the project with the _*.AppHost_ suffix), add a reference to the component consuming project. If you're using Visual Studio, you can use the **Add .NET Aspire Orchestrator Support** project context menu item to add the reference automatically. The following code snippet shows the project reference of the _AspireApp.AppHost.csproj_: :::code language="xml" source="snippets/components/AspireApp/AspireApp.AppHost/AspireApp.AppHost.csproj" highlight="16"::: For more information about AppHost tooling features, see [Add .NET Aspire Orchestrator Support](setup-tooling.md#add-orchestration-projects). - After the project is referenced in the orchestrator project, the component consuming project has its _Program.cs_ file updated to call the `AddServiceDefaults`. For more information about the service defaults project and its purpose, see [.NET Aspire service defaults](service-defaults.md). + After the project is referenced in the orchestrator project, the component consuming project has its _Program.cs_ file updated to call the `AddServiceDefaults`. + +1. In the orchestrator project, update the _Program.cs_ file with the following code: -1. TODO: show the app host _Program.cs_ file + :::code source="snippets/components/AspireApp/AspireApp.AppHost/Program.cs" highlight="3-4,6,8-11"::: -1. Add a connection string with a matching name in your _appsettings.json_ file. + In the preceding code, the orchestrator project: + + - Calls and chains a call to , adding a PostgreSQL database container to the app host. + - Establishes a connection to the PostgreSQL database using the connection name `"PostgreSqlConnection"`, by calling . + - Chains calls on the result of the from the Worker Service project: + - Calls to add a reference to the `database`. + - Calls to add a reference to the `databaseConnection`. + - Calls to set the number of replicas to `3`. + +1. Add a connection string with a matching name in your _appsettings.Development.json_ file of the orchestrator project. ```json { @@ -85,15 +96,11 @@ The following table lists the .NET Aspire components currently available for use } ``` -1. Inject the `NpgsqlDataSource` object into your controllers or service endpoints to run commands against the database: +1. Inject the `NpgsqlDataSource` object into the `Worker` to run commands against the database: - ```csharp - public class ExampleService(NpgsqlDataSource dataSource) - { - } - ``` + :::code source="snippets/components/AspireApp/WorkerService/Worker.cs" highlight="7,13"::: -After four steps, you now have a fully configured PostgreSQL database component integrated into your app. This component also configured health checks, logging, tracing, metrics, retries, and other useful capabilities for you behind the scenes. .NET Aspire components provide various options to configure each of these features. +After several steps, you now have a fully configured PostgreSQL database component and corresponding container with connection integrated into your app. This component also configured health checks, logging, tracing, metrics, retries, and other useful capabilities for you behind the scenes. .NET Aspire components provide various options to configure each of these features. ## Configure .NET Aspire components diff --git a/docs/snippets/components/AspireApp/AspireApp.AppHost/Program.cs b/docs/snippets/components/AspireApp/AspireApp.AppHost/Program.cs index 764311f27..164de672c 100644 --- a/docs/snippets/components/AspireApp/AspireApp.AppHost/Program.cs +++ b/docs/snippets/components/AspireApp/AspireApp.AppHost/Program.cs @@ -1,10 +1,13 @@ var builder = DistributedApplication.CreateBuilder(args); -var database = builder.AddPostgresContainer("PostgreSqlConnection") - .AddDatabase("dbname"); +var database = builder.AddPostgresContainer("postgres") + .AddDatabase("test"); + +var databaseConnection = builder.AddPostgresConnection("PostgreSqlConnection"); builder.AddProject("workerservice") .WithReference(database) - .WithReplicas(5); + .WithReference(databaseConnection) + .WithReplicas(3); builder.Build().Run(); diff --git a/docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.Development.json b/docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.Development.json index 0c208ae91..9d9c69334 100644 --- a/docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.Development.json +++ b/docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.Development.json @@ -1,8 +1,11 @@ { - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "ConnectionStrings": { + "PostgreSqlConnection": "Host=myserver;Database=test" } - } } diff --git a/docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.json b/docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.json index 31c092aa4..27a39347d 100644 --- a/docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.json +++ b/docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.json @@ -1,9 +1,9 @@ { - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning", - "Aspire.Hosting.Dcp": "Warning" + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "Aspire.Hosting.Dcp": "Warning" + } } - } } diff --git a/docs/snippets/components/AspireApp/WorkerService/Worker.cs b/docs/snippets/components/AspireApp/WorkerService/Worker.cs index f79cc6abc..a203f7225 100644 --- a/docs/snippets/components/AspireApp/WorkerService/Worker.cs +++ b/docs/snippets/components/AspireApp/WorkerService/Worker.cs @@ -12,7 +12,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) { // Use the dataSource - await Task.Delay(1_000, stoppingToken); + await Task.Delay(15_000, stoppingToken); } } } From 8cdd77d4a3cc14884dfef4890c99be6123ec8b4b Mon Sep 17 00:00:00 2001 From: David Pine Date: Tue, 5 Dec 2023 09:55:15 -0600 Subject: [PATCH 3/7] Fix an misrepresentation in config --- docs/components-overview.md | 15 ++++++--------- docs/database/postgresql-component.md | 15 ++++++++------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/docs/components-overview.md b/docs/components-overview.md index aab15067a..b574cf60f 100644 --- a/docs/components-overview.md +++ b/docs/components-overview.md @@ -48,15 +48,14 @@ For more information on working with .NET Aspire components in Visual Studio, se # [PackageReference](#tab/package-reference) ```xml - + ``` --- For more information, see [dotnet add package](/dotnet/core/tools/dotnet-add-package) or [Manage package dependencies in .NET applications](/dotnet/core/tools/dependencies). -1. In the _Program.cs_ file of your Worker Service project, call the extension method to register a `NpgsqlDataSource` for use via the dependency injection container. The method expects a connection name parameter. +1. In the _Program.cs_ file of your Worker Service project, call the extension method to register `NpgsqlDataSource` as a service. :::code source="snippets/components/AspireApp/WorkerService/Program.cs" highlight="5"::: @@ -65,21 +64,19 @@ For more information on working with .NET Aspire components in Visual Studio, se > [!TIP] > Components that are designed to connect to Azure services also support passwordless authentication and authorization using [Azure RBAC](/azure/role-based-access-control/overview), which is the recommended approach for production apps. -1. In your orchestrator project (the project with the _*.AppHost_ suffix), add a reference to the component consuming project. If you're using Visual Studio, you can use the **Add .NET Aspire Orchestrator Support** project context menu item to add the reference automatically. The following code snippet shows the project reference of the _AspireApp.AppHost.csproj_: +1. In your orchestrator project (the project with the _*.AppHost_ suffix), add a reference to the Worker Service project. If you're using Visual Studio, you can use the [**Add .NET Aspire Orchestrator Support**](setup-tooling.md#add-orchestration-projects) project context menu item to add the reference automatically. The following code snippet shows the project reference of the _AspireApp.AppHost.csproj_: :::code language="xml" source="snippets/components/AspireApp/AspireApp.AppHost/AspireApp.AppHost.csproj" highlight="16"::: - For more information about AppHost tooling features, see [Add .NET Aspire Orchestrator Support](setup-tooling.md#add-orchestration-projects). - - After the project is referenced in the orchestrator project, the component consuming project has its _Program.cs_ file updated to call the `AddServiceDefaults`. + After the Worker Service project is referenced in the orchestrator project, the Worker Service project has its _Program.cs_ file updated to call the `AddServiceDefaults`. For more information on service defaults, see [Service defaults](service-defaults.md). 1. In the orchestrator project, update the _Program.cs_ file with the following code: :::code source="snippets/components/AspireApp/AspireApp.AppHost/Program.cs" highlight="3-4,6,8-11"::: - In the preceding code, the orchestrator project: + The preceding code: - - Calls and chains a call to , adding a PostgreSQL database container to the app host. + - Calls and chains a call to , adding a PostgreSQL database container to the app model. - Establishes a connection to the PostgreSQL database using the connection name `"PostgreSqlConnection"`, by calling . - Chains calls on the result of the from the Worker Service project: - Calls to add a reference to the `database`. diff --git a/docs/database/postgresql-component.md b/docs/database/postgresql-component.md index 6995068c0..1a2eba56b 100644 --- a/docs/database/postgresql-component.md +++ b/docs/database/postgresql-component.md @@ -1,7 +1,7 @@ --- title: .NET Aspire PostgreSQL component description: This article describes the .NET Aspire PostgreSQL component. -ms.date: 11/15/2023 +ms.date: 12/05/2023 ms.topic: how-to --- @@ -22,8 +22,7 @@ dotnet add package Aspire.Npgsql --prerelease ### [PackageReference](#tab/package-reference) ```xml - + ``` --- @@ -43,7 +42,7 @@ After adding `NpgsqlDataSource` to the builder, you can get the `NpgsqlDataSourc ```csharp public class ExampleService(NpgsqlDataSource dataSource) { - // Use datasource... + // Use dataSource... } ``` @@ -77,9 +76,11 @@ The following example shows an _appsettings.json_ file that configures some of t ```json { - "Aspire.PostgreSql.Npgsql": { - "ConnectionString": "YOUR_CONNECTIONSTRING", - "Metrics": false + "Aspire": { + "Npgsql": { + "HealthChecks": false, + "Tracing": false + } } } ``` From a9402a39f3449ad6c245462e865b0648e11804f8 Mon Sep 17 00:00:00 2001 From: David Pine Date: Tue, 5 Dec 2023 10:00:52 -0600 Subject: [PATCH 4/7] Add space after xref --- docs/database/postgresql-component.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/database/postgresql-component.md b/docs/database/postgresql-component.md index 1a2eba56b..1ee4092de 100644 --- a/docs/database/postgresql-component.md +++ b/docs/database/postgresql-component.md @@ -107,7 +107,7 @@ var exampleProject = builder.AddProject() .WithReference(postgresdb); ``` -The method configures a connection in the `ExampleProject` named `postgresdb`. In the _Program.cs_ file of the `ExampleService` project, the database connection can be consumed using: +The method configures a connection in the `ExampleProject` named `postgresdb`. In the _Program.cs_ file of the `ExampleService` project, the database connection can be consumed using: ```csharp builder.AddNpgsqlDataSource("postgresdb"); From ee6a216cb7343d922f83f0dc770aa34395c1e3a0 Mon Sep 17 00:00:00 2001 From: David Pine Date: Tue, 5 Dec 2023 10:25:02 -0600 Subject: [PATCH 5/7] Fix and simplify example --- docs/components-overview.md | 18 +++--------------- .../AspireApp/AspireApp.AppHost/Program.cs | 7 ++----- .../appsettings.Development.json | 3 --- .../AspireApp/WorkerService/Program.cs | 2 +- 4 files changed, 6 insertions(+), 24 deletions(-) diff --git a/docs/components-overview.md b/docs/components-overview.md index b574cf60f..55d1adc82 100644 --- a/docs/components-overview.md +++ b/docs/components-overview.md @@ -59,7 +59,7 @@ For more information on working with .NET Aspire components in Visual Studio, se :::code source="snippets/components/AspireApp/WorkerService/Program.cs" highlight="5"::: - The preceding code adds the `NpgsqlDataSource` to the dependency injection container with the connection name of `"PostgreSqlConnection"`. The connection name is later used by the orchestrator project, when expressing resource dependencies. + The preceding code adds the `NpgsqlDataSource` to the dependency injection container with the connection name of `"customers"`. The connection name is later used by the orchestrator project, when expressing resource dependencies. > [!TIP] > Components that are designed to connect to Azure services also support passwordless authentication and authorization using [Azure RBAC](/azure/role-based-access-control/overview), which is the recommended approach for production apps. @@ -72,27 +72,15 @@ For more information on working with .NET Aspire components in Visual Studio, se 1. In the orchestrator project, update the _Program.cs_ file with the following code: - :::code source="snippets/components/AspireApp/AspireApp.AppHost/Program.cs" highlight="3-4,6,8-11"::: + :::code source="snippets/components/AspireApp/AspireApp.AppHost/Program.cs" highlight="3-4,6-8"::: The preceding code: - - Calls and chains a call to , adding a PostgreSQL database container to the app model. - - Establishes a connection to the PostgreSQL database using the connection name `"PostgreSqlConnection"`, by calling . + - Calls and chains a call to , adding a PostgreSQL database container to the app model with a database named `"customers"`. - Chains calls on the result of the from the Worker Service project: - Calls to add a reference to the `database`. - - Calls to add a reference to the `databaseConnection`. - Calls to set the number of replicas to `3`. -1. Add a connection string with a matching name in your _appsettings.Development.json_ file of the orchestrator project. - - ```json - { - "ConnectionStrings": { - "PostgreSqlConnection": "Host=myserver;Database=test" - } - } - ``` - 1. Inject the `NpgsqlDataSource` object into the `Worker` to run commands against the database: :::code source="snippets/components/AspireApp/WorkerService/Worker.cs" highlight="7,13"::: diff --git a/docs/snippets/components/AspireApp/AspireApp.AppHost/Program.cs b/docs/snippets/components/AspireApp/AspireApp.AppHost/Program.cs index 164de672c..62501c250 100644 --- a/docs/snippets/components/AspireApp/AspireApp.AppHost/Program.cs +++ b/docs/snippets/components/AspireApp/AspireApp.AppHost/Program.cs @@ -1,13 +1,10 @@ var builder = DistributedApplication.CreateBuilder(args); -var database = builder.AddPostgresContainer("postgres") - .AddDatabase("test"); - -var databaseConnection = builder.AddPostgresConnection("PostgreSqlConnection"); +var database = builder.AddPostgresContainer("postgresql") + .AddDatabase("PostgreSqlConnection"); builder.AddProject("workerservice") .WithReference(database) - .WithReference(databaseConnection) .WithReplicas(3); builder.Build().Run(); diff --git a/docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.Development.json b/docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.Development.json index 9d9c69334..a34cd70c5 100644 --- a/docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.Development.json +++ b/docs/snippets/components/AspireApp/AspireApp.AppHost/appsettings.Development.json @@ -4,8 +4,5 @@ "Default": "Information", "Microsoft.AspNetCore": "Warning" } - }, - "ConnectionStrings": { - "PostgreSqlConnection": "Host=myserver;Database=test" } } diff --git a/docs/snippets/components/AspireApp/WorkerService/Program.cs b/docs/snippets/components/AspireApp/WorkerService/Program.cs index edadfa3a0..a97e3491e 100644 --- a/docs/snippets/components/AspireApp/WorkerService/Program.cs +++ b/docs/snippets/components/AspireApp/WorkerService/Program.cs @@ -2,7 +2,7 @@ var builder = Host.CreateApplicationBuilder(args); -builder.AddNpgsqlDataSource("PostgreSqlConnection"); +builder.AddNpgsqlDataSource("customers"); builder.AddServiceDefaults(); builder.Services.AddHostedService(); From 650f4b0447c91bc6b23e4bd31eb661cf930402ad Mon Sep 17 00:00:00 2001 From: David Pine Date: Tue, 5 Dec 2023 10:25:39 -0600 Subject: [PATCH 6/7] Another missing change --- docs/snippets/components/AspireApp/AspireApp.AppHost/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/snippets/components/AspireApp/AspireApp.AppHost/Program.cs b/docs/snippets/components/AspireApp/AspireApp.AppHost/Program.cs index 62501c250..f2b0914df 100644 --- a/docs/snippets/components/AspireApp/AspireApp.AppHost/Program.cs +++ b/docs/snippets/components/AspireApp/AspireApp.AppHost/Program.cs @@ -1,7 +1,7 @@ var builder = DistributedApplication.CreateBuilder(args); var database = builder.AddPostgresContainer("postgresql") - .AddDatabase("PostgreSqlConnection"); + .AddDatabase("customers"); builder.AddProject("workerservice") .WithReference(database) From b455bd70eba3e28e452d4a754ceaced725e487bb Mon Sep 17 00:00:00 2001 From: David Pine Date: Tue, 5 Dec 2023 13:52:08 -0600 Subject: [PATCH 7/7] Apply suggestions from code review Co-authored-by: Andy (Steve) De George <67293991+adegeo@users.noreply.github.com> --- docs/components-overview.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/components-overview.md b/docs/components-overview.md index 55d1adc82..7cf53ca7a 100644 --- a/docs/components-overview.md +++ b/docs/components-overview.md @@ -35,9 +35,9 @@ For more information on working with .NET Aspire components in Visual Studio, se ## Explore a sample component workflow -.NET Aspire components streamline the process of consuming popular services and platforms. For example, consider the **.NET Aspire Application** template. With this template, you get the [AppHost](app-host-overview.md) and [ServiceDefaults](service-defaults.md) projects. Imagine that you have a need for a Worker Service project to perform some database processing. You could use the [.NET Aspire PostgreSQL component](database/postgresql-component.md) to connect to and utilize a PostgreSQL database. The database could be hosted on-prem or in a cloud service such as Azure, AWS, or GCP. The following steps demonstrate how to integrate this component into your app: +.NET Aspire components streamline the process of consuming popular services and platforms. For example, consider the **.NET Aspire Application** template. With this template, you get the [AppHost](app-host-overview.md) and [ServiceDefaults](service-defaults.md) projects. Imagine that you have a need for a worker service to perform some database processing. You could use the [.NET Aspire PostgreSQL component](database/postgresql-component.md) to connect to and utilize a PostgreSQL database. The database could be hosted on-prem or in a cloud service such as Azure, AWS, or GCP. The following steps demonstrate how to integrate this component into your app: -1. In the component consuming (Worker Service) project, install the [Aspire.Npgsql](https://www.nuget.org/packages/Aspire.Npgsql) NuGet package. +1. In the component consuming (worker service) project, install the [Aspire.Npgsql](https://www.nuget.org/packages/Aspire.Npgsql) NuGet package. # [.NET CLI](#tab/dotnet-cli) @@ -55,7 +55,7 @@ For more information on working with .NET Aspire components in Visual Studio, se For more information, see [dotnet add package](/dotnet/core/tools/dotnet-add-package) or [Manage package dependencies in .NET applications](/dotnet/core/tools/dependencies). -1. In the _Program.cs_ file of your Worker Service project, call the extension method to register `NpgsqlDataSource` as a service. +1. In the _Program.cs_ file of your worker service project, call the extension method to register `NpgsqlDataSource` as a service. :::code source="snippets/components/AspireApp/WorkerService/Program.cs" highlight="5"::: @@ -64,11 +64,11 @@ For more information on working with .NET Aspire components in Visual Studio, se > [!TIP] > Components that are designed to connect to Azure services also support passwordless authentication and authorization using [Azure RBAC](/azure/role-based-access-control/overview), which is the recommended approach for production apps. -1. In your orchestrator project (the project with the _*.AppHost_ suffix), add a reference to the Worker Service project. If you're using Visual Studio, you can use the [**Add .NET Aspire Orchestrator Support**](setup-tooling.md#add-orchestration-projects) project context menu item to add the reference automatically. The following code snippet shows the project reference of the _AspireApp.AppHost.csproj_: +1. In your orchestrator project (the project with the _*.AppHost_ suffix), add a reference to the worker service project. If you're using Visual Studio, you can use the [**Add .NET Aspire Orchestrator Support**](setup-tooling.md#add-orchestration-projects) project context menu item to add the reference automatically. The following code snippet shows the project reference of the _AspireApp.AppHost.csproj_: :::code language="xml" source="snippets/components/AspireApp/AspireApp.AppHost/AspireApp.AppHost.csproj" highlight="16"::: - After the Worker Service project is referenced in the orchestrator project, the Worker Service project has its _Program.cs_ file updated to call the `AddServiceDefaults`. For more information on service defaults, see [Service defaults](service-defaults.md). + After the worker service is referenced by the orchestrator project, the worker service project has its _Program.cs_ file updated to call the `AddServiceDefaults` method. For more information on service defaults, see [Service defaults](service-defaults.md). 1. In the orchestrator project, update the _Program.cs_ file with the following code: @@ -77,7 +77,7 @@ For more information on working with .NET Aspire components in Visual Studio, se The preceding code: - Calls and chains a call to , adding a PostgreSQL database container to the app model with a database named `"customers"`. - - Chains calls on the result of the from the Worker Service project: + - Chains calls on the result of the from the worker service project: - Calls to add a reference to the `database`. - Calls to set the number of replicas to `3`. @@ -85,7 +85,7 @@ For more information on working with .NET Aspire components in Visual Studio, se :::code source="snippets/components/AspireApp/WorkerService/Worker.cs" highlight="7,13"::: -After several steps, you now have a fully configured PostgreSQL database component and corresponding container with connection integrated into your app. This component also configured health checks, logging, tracing, metrics, retries, and other useful capabilities for you behind the scenes. .NET Aspire components provide various options to configure each of these features. +You now have a fully configured PostgreSQL database component and corresponding container with connection integrated into your app! This component also configured health checks, logging, metrics, retries, and other useful capabilities for you behind the scenes. .NET Aspire components provide various options to configure each of these features. ## Configure .NET Aspire components