diff --git a/docs/fundamentals/integrations-overview.md b/docs/fundamentals/integrations-overview.md index 6953de4524..480aff9a6c 100644 --- a/docs/fundamentals/integrations-overview.md +++ b/docs/fundamentals/integrations-overview.md @@ -66,6 +66,46 @@ When you add a client integration to a project within your .NET Aspire solution, - **[Health checks](health-checks.md)**: Exposes HTTP endpoints to provide basic availability and state information about an app. Health checks are used to influence decisions made by container orchestrators, load balancers, API gateways, and other management services. - **[Resiliency](/dotnet/core/resilience/http-resilience)**: The ability of your system to react to failure and still remain functional. Resiliency extends beyond preventing failures to include recovering and reconstructing your cloud-native environment back to a healthy state. +## Understand host integration extension methods + +Aspire hosting integrations provide extension methods that start with either `Add` or `With`. These methods conform to the following pattern: + +- **`Add*` methods**: `Add*` methods create and register new resources within the AppHost and return an `IResourceBuilder` where `TResource` is the concrete resource type added. This lets you continue fluent configuration on the returned builder. For example, calling returns an `IResourceBuilder`, and then calling on that namespace builder returns an `IResourceBuilder`. This pattern models parent-child relationships (for example, a Service Bus namespace and its queues or topics) while preserving a consistent fluent builder API. +- **`With*` methods**: Use `With*` methods to configure or enhance an existing resource. These methods typically return the same object type as the parent, allowing you to chain additional configuration calls. + +> [!IMPORTANT] +> When using `Add` methods, make sure to pass the correct resource object to your client integration. Passing the wrong object can result in misconfigured connections or runtime errors. + +Consider this code: + +```csharp +var serviceBus = builder.AddAzureServiceBus(name: "serviceBus") + .AddServiceBusTopic(name: "messagetopic"); + +var apiService = builder.AddProject("apiservice") + .WithHttpHealthCheck("/health") + .WithReference(serviceBus); + +// The serviceBus is an IResourceBuilder type +``` + +You may expect `serviceBus` to represent the Azure Service Bus resource but in fact, because you called on the same line, `serviceBus` is an Azure Service Bus topic resource. To avoid this result, call `AddServiceBusTopic` on a separate line: + +```csharp +var serviceBus = builder.AddAzureServiceBus(name: "serviceBus"); +var topic = serviceBus.AddServiceBusTopic(name: "messagetopic"); + +var apiService = builder.AddProject("apiservice") + .WithHttpHealthCheck("/health") + .WithReference(serviceBus); + +// The serviceBus is an IResourceBuilder type +``` + +Now, you can choose to pass the resource that consuming project needs. Either, as in the example, the Service Bus resource or the topic resource. + +This distinction helps you model your application's infrastructure accurately and ensures that client integrations receive the correct connection information. + ## Versioning considerations Hosting and client integrations are updated each release to target the latest stable versions of dependent resources. When container images are updated with new image versions, the hosting integrations update to these new versions. Similarly, when a new NuGet version is available for a dependent client library, the corresponding client integration updates to the new version. This ensures the latest features and security updates are available to applications. The .NET Aspire update type (major, minor, patch) doesn't necessarily indicate the type of update in dependent resources. For example, a new major version of a dependent resource may be updated in a .NET Aspire patch release, if necessary.