Skip to content

Commit 7753ddf

Browse files
authored
Add hosting integration section to text-to-image quickstart (#49896)
1 parent 2904504 commit 7753ddf

File tree

6 files changed

+163
-0
lines changed

6 files changed

+163
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// <SnippetSetup>
2+
using Aspire.Azure.AI.OpenAI;
3+
using Microsoft.Extensions.AI;
4+
using OpenAI;
5+
6+
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
7+
8+
// Add the Azure OpenAI client using hosting integration.
9+
AspireAzureOpenAIClientBuilder openai = builder.AddAzureOpenAIClient("openai");
10+
// </SnippetSetup>
11+
12+
// <SnippetAddImageGenerator>
13+
// Register the image generator with dependency injection.
14+
ImageGeneratorBuilder imageBuilder = builder.Services.AddImageGenerator(services =>
15+
{
16+
OpenAIClient openAiClient = services.GetRequiredService<OpenAIClient>();
17+
OpenAI.Images.ImageClient imageClient = openAiClient.GetImageClient("gpt-image-1");
18+
#pragma warning disable MEAI001 // Type is for evaluation purposes only.
19+
return imageClient.AsIImageGenerator();
20+
#pragma warning restore MEAI001
21+
});
22+
// </SnippetAddImageGenerator>
23+
24+
// <SnippetConfigureOptions>
25+
imageBuilder.ConfigureOptions(options =>
26+
{
27+
options.MediaType = "image/png";
28+
}).UseLogging();
29+
// </SnippetConfigureOptions>
30+
31+
WebApplication app = builder.Build();
32+
33+
// <SnippetUseImageGenerator>
34+
// Use the image generator in an endpoint.
35+
app.MapPost("/generate-image", async (IImageGenerator generator, string prompt) =>
36+
{
37+
ImageGenerationResponse response = await generator.GenerateImagesAsync(prompt);
38+
DataContent dataContent = response.Contents.OfType<DataContent>().First();
39+
40+
return Results.File(dataContent.Data.ToArray(), "image/png");
41+
});
42+
// </SnippetUseImageGenerator>
43+
44+
app.Run();
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"$schema": "https://json.schemastore.org/launchsettings.json",
3+
"profiles": {
4+
"http": {
5+
"commandName": "Project",
6+
"dotnetRunMessages": true,
7+
"launchBrowser": true,
8+
"applicationUrl": "http://localhost:5219",
9+
"environmentVariables": {
10+
"ASPNETCORE_ENVIRONMENT": "Development"
11+
}
12+
},
13+
"https": {
14+
"commandName": "Project",
15+
"dotnetRunMessages": true,
16+
"launchBrowser": true,
17+
"applicationUrl": "https://localhost:7210;http://localhost:5219",
18+
"environmentVariables": {
19+
"ASPNETCORE_ENVIRONMENT": "Development"
20+
}
21+
}
22+
}
23+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net10.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<NoWarn>$(NoWarn);MEAI001</NoWarn>
8+
<UserSecretsId>a9e545e9-e2b5-4e1b-81ce-217ca2d281c6</UserSecretsId>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Aspire.Azure.AI.OpenAI" Version="13.0.0-preview.1.25560.3" />
13+
<PackageReference Include="Azure.AI.OpenAI" Version="2.5.0-beta.1" />
14+
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" Version="10.0.0-preview.1.25560.10" />
15+
</ItemGroup>
16+
17+
</Project>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
}
8+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
},
8+
"AllowedHosts": "*",
9+
"ConnectionStrings": {
10+
"openai": "Endpoint=https://your-endpoint.com/;Key=your-api-key"
11+
}
12+
}

docs/ai/quickstarts/text-to-image.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,65 @@ You can customize image generation by providing other options such as size, resp
100100
- <xref:Microsoft.Extensions.AI.ImageGenerationOptions.RawRepresentationFactory>: The callback that creates the raw representation of the image generation options from an underlying implementation.
101101
- <xref:Microsoft.Extensions.AI.ImageGenerationOptions.ResponseFormat>: Options are <xref:Microsoft.Extensions.AI.ImageGenerationResponseFormat.Uri>, <xref:Microsoft.Extensions.AI.ImageGenerationResponseFormat.Data>, and <xref:Microsoft.Extensions.AI.ImageGenerationResponseFormat.Hosted>.
102102
103+
## Use hosting integration
104+
105+
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.
106+
107+
### Configure hosting services
108+
109+
The `Aspire.Azure.AI.OpenAI` package provides extension methods to register Azure OpenAI services with your application's dependency injection container:
110+
111+
1. Add the necessary packages to your web application:
112+
113+
```dotnetcli
114+
dotnet add package Aspire.Azure.AI.OpenAI --prerelease
115+
dotnet add package Azure.AI.OpenAI
116+
dotnet add package Microsoft.Extensions.AI.OpenAI --prerelease
117+
```
118+
119+
1. Configure the Azure OpenAI client and image generator in your `Program.cs` file:
120+
121+
:::code language="csharp" source="snippets/text-to-image/hosting/Program.cs" id="SnippetSetup":::
122+
123+
The <xref:Microsoft.Extensions.Hosting.AspireAzureOpenAIExtensions.AddAzureOpenAIClient(Microsoft.Extensions.Hosting.IHostApplicationBuilder,System.String,System.Action{Aspire.Azure.AI.OpenAI.AzureOpenAISettings},System.Action{Azure.Core.Extensions.IAzureClientBuilder{Azure.AI.OpenAI.AzureOpenAIClient,Azure.AI.OpenAI.AzureOpenAIClientOptions}})> 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:
124+
125+
```json
126+
{
127+
"ConnectionStrings": {
128+
"openai": "Endpoint=https://your-resource-name.openai.azure.com/;Key=your-api-key"
129+
}
130+
}
131+
```
132+
133+
1. Register the <xref:Microsoft.Extensions.AI.IImageGenerator> service with dependency injection:
134+
135+
:::code language="csharp" source="snippets/text-to-image/hosting/Program.cs" id="SnippetAddImageGenerator":::
136+
137+
The <xref:Microsoft.Extensions.DependencyInjection.ImageGeneratorBuilderServiceCollectionExtensions.AddImageGenerator*> method registers the image generator as a singleton service that can be injected into controllers, services, or minimal API endpoints.
138+
139+
1. Add options and logging::
140+
141+
:::code language="csharp" source="snippets/text-to-image/hosting/Program.cs" id="SnippetConfigureOptions":::
142+
143+
The preceding code:
144+
145+
- Configures options by calling the <xref:Microsoft.Extensions.AI.ConfigureOptionsImageGeneratorBuilderExtensions.ConfigureOptions(Microsoft.Extensions.AI.ImageGeneratorBuilder,System.Action{Microsoft.Extensions.AI.ImageGenerationOptions})> extension method on the <xref:Microsoft.Extensions.AI.ImageGeneratorBuilder>. This method configures the <xref:Microsoft.Extensions.AI.ImageGenerationOptions> to be passed to the next generator in the pipeline.
146+
- Adds logging to the image generator pipeline by calling the <xref:Microsoft.Extensions.AI.LoggingImageGeneratorBuilderExtensions.UseLogging(Microsoft.Extensions.AI.ImageGeneratorBuilder,Microsoft.Extensions.Logging.ILoggerFactory,System.Action{Microsoft.Extensions.AI.LoggingImageGenerator})> extension method.
147+
148+
### Use the image generator in endpoints
149+
150+
Once registered, you can inject `IImageGenerator` into your endpoints or services:
151+
152+
:::code language="csharp" source="snippets/text-to-image/hosting/Program.cs" id="SnippetUseImageGenerator":::
153+
154+
This hosting approach provides several benefits:
155+
156+
- **Configuration management**: Connection strings and settings are managed through the .NET configuration system.
157+
- **Dependency injection**: The image generator is available throughout your application via DI.
158+
- **Lifecycle management**: Services are properly initialized and disposed of by the hosting infrastructure.
159+
- **Testability**: Mock implementations can be easily substituted for testing.
160+
- **Integration with .NET Aspire**: When using .NET Aspire, the `AddAzureOpenAIClient` method integrates with service discovery and telemetry.
161+
103162
## Best practices
104163

105164
When implementing text-to-image generation in your applications, consider these best practices:

0 commit comments

Comments
 (0)