From 6a9cdfb10fbabe4d7abd495609ca8db44f5d2ba1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 14 Nov 2025 01:25:24 +0000 Subject: [PATCH 1/5] Initial plan From 38c81903b4c04bf1536930168ea0dc54b5e41c8b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 14 Nov 2025 01:33:25 +0000 Subject: [PATCH 2/5] Add hosting integration section to text-to-image article with code examples Co-authored-by: gewarren <24882762+gewarren@users.noreply.github.com> --- .../hosting/TextToImageHosting/Program.cs | 41 +++++++++++++++ .../Properties/launchSettings.json | 23 +++++++++ .../TextToImageHosting.csproj | 16 ++++++ .../appsettings.Development.json | 8 +++ .../TextToImageHosting/appsettings.json | 12 +++++ docs/ai/quickstarts/text-to-image.md | 50 +++++++++++++++++++ 6 files changed, 150 insertions(+) create mode 100644 docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/Program.cs create mode 100644 docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/Properties/launchSettings.json create mode 100644 docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/TextToImageHosting.csproj create mode 100644 docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/appsettings.Development.json create mode 100644 docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/appsettings.json diff --git a/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/Program.cs b/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/Program.cs new file mode 100644 index 0000000000000..9032719954af0 --- /dev/null +++ b/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/Program.cs @@ -0,0 +1,41 @@ +// +using Microsoft.Extensions.AI; +using OpenAI; + +var builder = WebApplication.CreateBuilder(args); + +// Add the Azure OpenAI client using hosting integration +var openai = builder.AddAzureOpenAIClient("openai"); +// + +// +// Register the image generator with dependency injection +builder.Services.AddImageGenerator(services => +{ + var openAiClient = services.GetRequiredService(); + var imageClient = openAiClient.GetImageClient("gpt-image-1"); + #pragma warning disable MEAI001 // Type is for evaluation purposes only. + return imageClient.AsIImageGenerator(); + #pragma warning restore MEAI001 +}); +// + +var app = builder.Build(); + +// +// Use the image generator in an endpoint +app.MapPost("/generate-image", async (IImageGenerator generator, string prompt) => +{ + var options = new ImageGenerationOptions + { + MediaType = "image/png" + }; + + var response = await generator.GenerateImagesAsync(prompt, options); + var dataContent = response.Contents.OfType().First(); + + return Results.File(dataContent.Data.ToArray(), "image/png"); +}); +// + +app.Run(); diff --git a/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/Properties/launchSettings.json b/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/Properties/launchSettings.json new file mode 100644 index 0000000000000..a320d48079109 --- /dev/null +++ b/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/Properties/launchSettings.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5219", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7210;http://localhost:5219", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/TextToImageHosting.csproj b/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/TextToImageHosting.csproj new file mode 100644 index 0000000000000..2b026f208bbac --- /dev/null +++ b/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/TextToImageHosting.csproj @@ -0,0 +1,16 @@ + + + + net9.0 + enable + enable + $(NoWarn);MEAI001 + + + + + + + + + diff --git a/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/appsettings.Development.json b/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/appsettings.Development.json new file mode 100644 index 0000000000000..0c208ae9181e5 --- /dev/null +++ b/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/appsettings.json b/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/appsettings.json new file mode 100644 index 0000000000000..9d00201ad9f00 --- /dev/null +++ b/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/appsettings.json @@ -0,0 +1,12 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "ConnectionStrings": { + "openai": "Endpoint=https://your-resource-name.openai.azure.com/;Key=your-api-key" + } +} diff --git a/docs/ai/quickstarts/text-to-image.md b/docs/ai/quickstarts/text-to-image.md index 326891d94041e..4d0753fb8569b 100644 --- a/docs/ai/quickstarts/text-to-image.md +++ b/docs/ai/quickstarts/text-to-image.md @@ -100,6 +100,56 @@ You can customize image generation by providing other options such as size, resp - : The callback that creates the raw representation of the image generation options from an underlying implementation. - : Options are , , and . +## Use hosting integration + +When building web applications or hosted services, you can integrate image generation using dependency injection and hosting patterns. This approach provides better lifecycle management, configuration integration, and testability. + +### Configure hosting services + +The `Aspire.Azure.AI.OpenAI` package provides extension methods to register Azure OpenAI services with your application's dependency injection container: + +1. Add the necessary packages to your web application: + + ```dotnetcli + dotnet add package Aspire.Azure.AI.OpenAI --prerelease + dotnet add package Azure.AI.OpenAI + dotnet add package Microsoft.Extensions.AI.OpenAI --prerelease + ``` + +1. Configure the Azure OpenAI client and image generator in your `Program.cs` file: + + :::code language="csharp" source="snippets/text-to-image/hosting/TextToImageHosting/Program.cs" id="SnippetSetup"::: + + The `AddAzureOpenAIClient` method registers the Azure OpenAI client with dependency injection. The connection string (named `"openai"`) is retrieved from configuration, typically from `appsettings.json` or environment variables: + + ```json + { + "ConnectionStrings": { + "openai": "Endpoint=https://your-resource-name.openai.azure.com/;Key=your-api-key" + } + } + ``` + +1. Register the `IImageGenerator` service with dependency injection: + + :::code language="csharp" source="snippets/text-to-image/hosting/TextToImageHosting/Program.cs" id="SnippetAddImageGenerator"::: + + The `AddImageGenerator` method registers the image generator as a singleton service that can be injected into controllers, services, or minimal API endpoints. + +### Use the image generator in endpoints + +Once registered, you can inject `IImageGenerator` into your endpoints or services: + +:::code language="csharp" source="snippets/text-to-image/hosting/TextToImageHosting/Program.cs" id="SnippetUseImageGenerator"::: + +This hosting approach provides several benefits: + +- **Configuration management**: Connection strings and settings are managed through the .NET configuration system. +- **Dependency injection**: The image generator is available throughout your application via DI. +- **Lifecycle management**: Services are properly initialized and disposed of by the hosting infrastructure. +- **Testability**: Mock implementations can be easily substituted for testing. +- **Integration with .NET Aspire**: When using .NET Aspire, the `AddAzureOpenAIClient` method integrates with service discovery and telemetry. + ## Best practices When implementing text-to-image generation in your applications, consider these best practices: From 8b5da8e0a5910be904e68411ad8ed0ebd3f49f73 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Thu, 13 Nov 2025 17:57:01 -0800 Subject: [PATCH 3/5] Update docs/ai/quickstarts/text-to-image.md --- docs/ai/quickstarts/text-to-image.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ai/quickstarts/text-to-image.md b/docs/ai/quickstarts/text-to-image.md index 4d0753fb8569b..99a748252eb6b 100644 --- a/docs/ai/quickstarts/text-to-image.md +++ b/docs/ai/quickstarts/text-to-image.md @@ -102,7 +102,7 @@ You can customize image generation by providing other options such as size, resp ## Use hosting integration -When building web applications or hosted services, you can integrate image generation using dependency injection and hosting patterns. This approach provides better lifecycle management, configuration integration, and testability. +When you build web apps or hosted services, you can integrate image generation using dependency injection and hosting patterns. This approach provides better lifecycle management, configuration integration, and testability. ### Configure hosting services From 3b9828b7d79dff9d88959c46f7b13cfbd3132590 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Fri, 14 Nov 2025 11:24:10 -0800 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../hosting/TextToImageHosting/TextToImageHosting.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/TextToImageHosting.csproj b/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/TextToImageHosting.csproj index 2b026f208bbac..244282745d335 100644 --- a/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/TextToImageHosting.csproj +++ b/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/TextToImageHosting.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 enable enable $(NoWarn);MEAI001 @@ -9,7 +9,7 @@ - + From 1e6f6e89ff3752b157d5d88daa20f7bdf554919c Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Tue, 18 Nov 2025 17:28:02 -0800 Subject: [PATCH 5/5] human edits 2 --- .../snippets/text-to-image/hosting/Program.cs | 42 +++++++++++++++++++ .../Properties/launchSettings.json | 0 .../TextToImageHosting.csproj | 5 ++- .../hosting/TextToImageHosting/Program.cs | 41 ------------------ .../appsettings.Development.json | 0 .../{TextToImageHosting => }/appsettings.json | 2 +- docs/ai/quickstarts/text-to-image.md | 12 +++--- 7 files changed, 52 insertions(+), 50 deletions(-) create mode 100644 docs/ai/quickstarts/snippets/text-to-image/hosting/Program.cs rename docs/ai/quickstarts/snippets/text-to-image/hosting/{TextToImageHosting => }/Properties/launchSettings.json (100%) rename docs/ai/quickstarts/snippets/text-to-image/hosting/{TextToImageHosting => }/TextToImageHosting.csproj (70%) delete mode 100644 docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/Program.cs rename docs/ai/quickstarts/snippets/text-to-image/hosting/{TextToImageHosting => }/appsettings.Development.json (100%) rename docs/ai/quickstarts/snippets/text-to-image/hosting/{TextToImageHosting => }/appsettings.json (66%) diff --git a/docs/ai/quickstarts/snippets/text-to-image/hosting/Program.cs b/docs/ai/quickstarts/snippets/text-to-image/hosting/Program.cs new file mode 100644 index 0000000000000..5eebcd4fd8067 --- /dev/null +++ b/docs/ai/quickstarts/snippets/text-to-image/hosting/Program.cs @@ -0,0 +1,42 @@ +// +using Aspire.Azure.AI.OpenAI; +using Microsoft.Extensions.AI; +using OpenAI; + +WebApplicationBuilder builder = WebApplication.CreateBuilder(args); + +// Add the Azure OpenAI client using hosting integration. +AspireAzureOpenAIClientBuilder openai = builder.AddAzureOpenAIClient("openai"); +// + +// +// Register the image generator with dependency injection. +builder.Services.AddImageGenerator(services => +{ + OpenAIClient openAiClient = services.GetRequiredService(); + OpenAI.Images.ImageClient imageClient = openAiClient.GetImageClient("gpt-image-1"); + #pragma warning disable MEAI001 // Type is for evaluation purposes only. + return imageClient.AsIImageGenerator(); + #pragma warning restore MEAI001 +}); +// + +WebApplication app = builder.Build(); + +// +// Use the image generator in an endpoint. +app.MapPost("/generate-image", async (IImageGenerator generator, string prompt) => +{ + var options = new ImageGenerationOptions + { + MediaType = "image/png" + }; + + ImageGenerationResponse response = await generator.GenerateImagesAsync(prompt, options); + DataContent dataContent = response.Contents.OfType().First(); + + return Results.File(dataContent.Data.ToArray(), "image/png"); +}); +// + +app.Run(); diff --git a/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/Properties/launchSettings.json b/docs/ai/quickstarts/snippets/text-to-image/hosting/Properties/launchSettings.json similarity index 100% rename from docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/Properties/launchSettings.json rename to docs/ai/quickstarts/snippets/text-to-image/hosting/Properties/launchSettings.json diff --git a/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/TextToImageHosting.csproj b/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting.csproj similarity index 70% rename from docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/TextToImageHosting.csproj rename to docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting.csproj index 244282745d335..63a42a18ed6ad 100644 --- a/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/TextToImageHosting.csproj +++ b/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting.csproj @@ -1,15 +1,16 @@ - + net10.0 enable enable $(NoWarn);MEAI001 + a9e545e9-e2b5-4e1b-81ce-217ca2d281c6 - + diff --git a/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/Program.cs b/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/Program.cs deleted file mode 100644 index 9032719954af0..0000000000000 --- a/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/Program.cs +++ /dev/null @@ -1,41 +0,0 @@ -// -using Microsoft.Extensions.AI; -using OpenAI; - -var builder = WebApplication.CreateBuilder(args); - -// Add the Azure OpenAI client using hosting integration -var openai = builder.AddAzureOpenAIClient("openai"); -// - -// -// Register the image generator with dependency injection -builder.Services.AddImageGenerator(services => -{ - var openAiClient = services.GetRequiredService(); - var imageClient = openAiClient.GetImageClient("gpt-image-1"); - #pragma warning disable MEAI001 // Type is for evaluation purposes only. - return imageClient.AsIImageGenerator(); - #pragma warning restore MEAI001 -}); -// - -var app = builder.Build(); - -// -// Use the image generator in an endpoint -app.MapPost("/generate-image", async (IImageGenerator generator, string prompt) => -{ - var options = new ImageGenerationOptions - { - MediaType = "image/png" - }; - - var response = await generator.GenerateImagesAsync(prompt, options); - var dataContent = response.Contents.OfType().First(); - - return Results.File(dataContent.Data.ToArray(), "image/png"); -}); -// - -app.Run(); diff --git a/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/appsettings.Development.json b/docs/ai/quickstarts/snippets/text-to-image/hosting/appsettings.Development.json similarity index 100% rename from docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/appsettings.Development.json rename to docs/ai/quickstarts/snippets/text-to-image/hosting/appsettings.Development.json diff --git a/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/appsettings.json b/docs/ai/quickstarts/snippets/text-to-image/hosting/appsettings.json similarity index 66% rename from docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/appsettings.json rename to docs/ai/quickstarts/snippets/text-to-image/hosting/appsettings.json index 9d00201ad9f00..2a36d2d501808 100644 --- a/docs/ai/quickstarts/snippets/text-to-image/hosting/TextToImageHosting/appsettings.json +++ b/docs/ai/quickstarts/snippets/text-to-image/hosting/appsettings.json @@ -7,6 +7,6 @@ }, "AllowedHosts": "*", "ConnectionStrings": { - "openai": "Endpoint=https://your-resource-name.openai.azure.com/;Key=your-api-key" + "openai": "Endpoint=https://your-endpoint.com/;Key=your-api-key" } } diff --git a/docs/ai/quickstarts/text-to-image.md b/docs/ai/quickstarts/text-to-image.md index 99a748252eb6b..1e49865c306bb 100644 --- a/docs/ai/quickstarts/text-to-image.md +++ b/docs/ai/quickstarts/text-to-image.md @@ -118,9 +118,9 @@ The `Aspire.Azure.AI.OpenAI` package provides extension methods to register Azur 1. Configure the Azure OpenAI client and image generator in your `Program.cs` file: - :::code language="csharp" source="snippets/text-to-image/hosting/TextToImageHosting/Program.cs" id="SnippetSetup"::: + :::code language="csharp" source="snippets/text-to-image/hosting/Program.cs" id="SnippetSetup"::: - The `AddAzureOpenAIClient` method registers the Azure OpenAI client with dependency injection. The connection string (named `"openai"`) is retrieved from configuration, typically from `appsettings.json` or environment variables: + The method registers the Azure OpenAI client with dependency injection. The connection string (named `"openai"`) is retrieved from configuration, typically from `appsettings.json` or environment variables: ```json { @@ -130,17 +130,17 @@ The `Aspire.Azure.AI.OpenAI` package provides extension methods to register Azur } ``` -1. Register the `IImageGenerator` service with dependency injection: +1. Register the service with dependency injection: - :::code language="csharp" source="snippets/text-to-image/hosting/TextToImageHosting/Program.cs" id="SnippetAddImageGenerator"::: + :::code language="csharp" source="snippets/text-to-image/hosting/Program.cs" id="SnippetAddImageGenerator"::: - The `AddImageGenerator` method registers the image generator as a singleton service that can be injected into controllers, services, or minimal API endpoints. + The method registers the image generator as a singleton service that can be injected into controllers, services, or minimal API endpoints. ### Use the image generator in endpoints Once registered, you can inject `IImageGenerator` into your endpoints or services: -:::code language="csharp" source="snippets/text-to-image/hosting/TextToImageHosting/Program.cs" id="SnippetUseImageGenerator"::: +:::code language="csharp" source="snippets/text-to-image/hosting/Program.cs" id="SnippetUseImageGenerator"::: This hosting approach provides several benefits: