Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ For snippets >6 lines:
1. All code should use the latest stable versions/features.
1. Create examples in both C# and Visual Basic unless the article referencing the snippet resides in the in the `csharp`, `fsharp`, and `visual-basic` language folders.
1. When you add code, use code comments sparingly because they don't get localized. You can use them to briefly clarify code-specific details (such as logic, parameters, or edge cases). Put any critical information and context in the markdown text of the referencing article.
1. IMPORTANT: For created code, always try to encapsulate it in an standalone executable (e.g. `dotnet fsi myFile.fsx` or `dotnet run myFile.cs`, add the necessary boilerplate/imports/usings where needed, and execute it.). Run it, and for every code snippet, include a PR commentary checking each code sample and proving what it has produced - this can be diagnostics, standard output, or a result value. That standalone file is just for the purpose of verification within copilot's execution environment, the published docs snippet should remain a subset as you would normally write to maximize clarity.

## File Naming

Expand All @@ -69,4 +70,4 @@ When assigned an issue or directly given a task in GitHub:
3. Check for build warnings in the OpenPublishing.Build status check
4. If warnings exist:
- Click "View Details" to open the build report
- Resolve any build warnings you introduced
- Resolve any build warnings you introduced
4 changes: 3 additions & 1 deletion .github/workflows/dependabot-bot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ jobs:
- name: "Print manual run reason"
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
echo "Reason: ${{ github.event.inputs.reason }}"
echo "Reason: $REASON"
env:
REASON: ${{ github.event.inputs.reason }}
# Run the .NET dependabot-bot tool
- name: dependabot-bot
id: dependabot-bot
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/quest-bulk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ jobs:
- name: "Print manual bulk import run reason"
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
echo "Reason: ${{ github.event.inputs.reason }}"
echo "Reason: $REASON"
env:
REASON: ${{ github.event.inputs.reason }}

- name: Azure OpenID Connect
id: azure-oidc-auth
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/quest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@ jobs:
- name: "Print manual run reason"
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
echo "Reason: ${{ github.event.inputs.reason }}"
echo "Issue number: ${{ github.event.inputs.issue }}"
echo "Reason: $REASON"
echo "Issue number: $ISSUENUMBER"
env:
REASON: ${{ github.event.inputs.reason }}
ISSUENUMBER: ${{ github.event.inputs.issue }}

- name: Azure OpenID Connect
id: azure-oidc-auth
Expand Down
44 changes: 44 additions & 0 deletions docs/ai/quickstarts/snippets/text-to-image/hosting/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// <SnippetSetup>
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");
// </SnippetSetup>

// <SnippetAddImageGenerator>
// Register the image generator with dependency injection.
ImageGeneratorBuilder imageBuilder = builder.Services.AddImageGenerator(services =>
{
OpenAIClient openAiClient = services.GetRequiredService<OpenAIClient>();
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
});
// </SnippetAddImageGenerator>

// <SnippetConfigureOptions>
imageBuilder.ConfigureOptions(options =>
{
options.MediaType = "image/png";
}).UseLogging();
// </SnippetConfigureOptions>

WebApplication app = builder.Build();

// <SnippetUseImageGenerator>
// Use the image generator in an endpoint.
app.MapPost("/generate-image", async (IImageGenerator generator, string prompt) =>
{
ImageGenerationResponse response = await generator.GenerateImagesAsync(prompt);
DataContent dataContent = response.Contents.OfType<DataContent>().First();

return Results.File(dataContent.Data.ToArray(), "image/png");
});
// </SnippetUseImageGenerator>

app.Run();
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<NoWarn>$(NoWarn);MEAI001</NoWarn>
<UserSecretsId>a9e545e9-e2b5-4e1b-81ce-217ca2d281c6</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Aspire.Azure.AI.OpenAI" Version="13.0.0-preview.1.25560.3" />
<PackageReference Include="Azure.AI.OpenAI" Version="2.5.0-beta.1" />
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" Version="10.0.0-preview.1.25560.10" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"openai": "Endpoint=https://your-endpoint.com/;Key=your-api-key"
}
}
59 changes: 59 additions & 0 deletions docs/ai/quickstarts/text-to-image.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,65 @@ You can customize image generation by providing other options such as size, resp
- <xref:Microsoft.Extensions.AI.ImageGenerationOptions.RawRepresentationFactory>: The callback that creates the raw representation of the image generation options from an underlying implementation.
- <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>.

## Use hosting integration

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

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/Program.cs" id="SnippetSetup":::

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:

```json
{
"ConnectionStrings": {
"openai": "Endpoint=https://your-resource-name.openai.azure.com/;Key=your-api-key"
}
}
```

1. Register the <xref:Microsoft.Extensions.AI.IImageGenerator> service with dependency injection:

:::code language="csharp" source="snippets/text-to-image/hosting/Program.cs" id="SnippetAddImageGenerator":::

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.

1. Add options and logging::

:::code language="csharp" source="snippets/text-to-image/hosting/Program.cs" id="SnippetConfigureOptions":::

The preceding code:

- 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.
- 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.

### 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/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:
Expand Down
2 changes: 1 addition & 1 deletion docs/azure/includes/dotnet-all.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
| WCF Storage Queues | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Microsoft.WCF.Azure.StorageQueues/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Microsoft.WCF.Azure.StorageQueues-readme?view=azure-dotnet-preview&amp;preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.WCF.Azure.StorageQueues_1.0.0-beta.1/sdk/extension-wcf/Microsoft.WCF.Azure.StorageQueues/) |
| Web PubSub | NuGet [1.6.0](https://www.nuget.org/packages/Azure.Messaging.WebPubSub/1.6.0) | [docs](/dotnet/api/overview/azure/Messaging.WebPubSub-readme) | GitHub [1.6.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.WebPubSub_1.6.0/sdk/webpubsub/Azure.Messaging.WebPubSub/) |
| Web PubSub Client | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Messaging.WebPubSub.Client/1.0.0) | [docs](/dotnet/api/overview/azure/Messaging.WebPubSub.Client-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.WebPubSub.Client_1.0.0/sdk/webpubsub/Azure.Messaging.WebPubSub.Client/) |
| Azure client library integration for ASP.NET Core | NuGet [1.13.0](https://www.nuget.org/packages/Microsoft.Extensions.Azure/1.13.0) | [docs](/dotnet/api/overview/azure/Microsoft.Extensions.Azure-readme) | GitHub [1.13.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Extensions.Azure_1.13.0/sdk/extensions/Microsoft.Extensions.Azure/) |
| Azure client library integration for ASP.NET Core | NuGet [1.13.1](https://www.nuget.org/packages/Microsoft.Extensions.Azure/1.13.1) | [docs](/dotnet/api/overview/azure/Microsoft.Extensions.Azure-readme) | GitHub [1.13.1](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Extensions.Azure_1.13.1/sdk/extensions/Microsoft.Extensions.Azure/) |
| Blob Storage Key Store for .NET Data Protection | NuGet [1.5.1](https://www.nuget.org/packages/Azure.Extensions.AspNetCore.DataProtection.Blobs/1.5.1) | [docs](/dotnet/api/overview/azure/Extensions.AspNetCore.DataProtection.Blobs-readme) | GitHub [1.5.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Extensions.AspNetCore.DataProtection.Blobs_1.5.1/sdk/extensions/Azure.Extensions.AspNetCore.DataProtection.Blobs/) |
| CloudNative CloudEvents with Event Grid | NuGet [1.0.0](https://www.nuget.org/packages/Microsoft.Azure.Messaging.EventGrid.CloudNativeCloudEvents/1.0.0) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.Messaging.EventGrid.CloudNativeCloudEvents-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.Messaging.EventGrid.CloudNativeCloudEvents_1.0.0/sdk/eventgrid/Microsoft.Azure.Messaging.EventGrid.CloudNativeCloudEvents/) |
| Core - Client - Spatial | NuGet [1.1.0](https://www.nuget.org/packages/Microsoft.Azure.Core.Spatial/1.1.0)<br>NuGet [1.2.0-beta.1](https://www.nuget.org/packages/Microsoft.Azure.Core.Spatial/1.2.0-beta.1) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.Core.Spatial-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.Core.Spatial_1.1.0/sdk/core/Microsoft.Azure.Core.Spatial/)<br>GitHub [1.2.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.Core.Spatial_1.2.0-beta.1/sdk/core/Microsoft.Azure.Core.Spatial/) |
Expand Down
2 changes: 1 addition & 1 deletion docs/azure/includes/dotnet-new.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@
| WCF Storage Queues | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Microsoft.WCF.Azure.StorageQueues/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Microsoft.WCF.Azure.StorageQueues-readme?view=azure-dotnet-preview&amp;preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.WCF.Azure.StorageQueues_1.0.0-beta.1/sdk/extension-wcf/Microsoft.WCF.Azure.StorageQueues/) |
| Web PubSub | NuGet [1.6.0](https://www.nuget.org/packages/Azure.Messaging.WebPubSub/1.6.0) | [docs](/dotnet/api/overview/azure/Messaging.WebPubSub-readme) | GitHub [1.6.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.WebPubSub_1.6.0/sdk/webpubsub/Azure.Messaging.WebPubSub/) |
| Web PubSub Client | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Messaging.WebPubSub.Client/1.0.0) | [docs](/dotnet/api/overview/azure/Messaging.WebPubSub.Client-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.WebPubSub.Client_1.0.0/sdk/webpubsub/Azure.Messaging.WebPubSub.Client/) |
| Azure client library integration for ASP.NET Core | NuGet [1.13.0](https://www.nuget.org/packages/Microsoft.Extensions.Azure/1.13.0) | [docs](/dotnet/api/overview/azure/Microsoft.Extensions.Azure-readme) | GitHub [1.13.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Extensions.Azure_1.13.0/sdk/extensions/Microsoft.Extensions.Azure/) |
| Azure client library integration for ASP.NET Core | NuGet [1.13.1](https://www.nuget.org/packages/Microsoft.Extensions.Azure/1.13.1) | [docs](/dotnet/api/overview/azure/Microsoft.Extensions.Azure-readme) | GitHub [1.13.1](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Extensions.Azure_1.13.1/sdk/extensions/Microsoft.Extensions.Azure/) |
| Blob Storage Key Store for .NET Data Protection | NuGet [1.5.1](https://www.nuget.org/packages/Azure.Extensions.AspNetCore.DataProtection.Blobs/1.5.1) | [docs](/dotnet/api/overview/azure/Extensions.AspNetCore.DataProtection.Blobs-readme) | GitHub [1.5.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Extensions.AspNetCore.DataProtection.Blobs_1.5.1/sdk/extensions/Azure.Extensions.AspNetCore.DataProtection.Blobs/) |
| CloudNative CloudEvents with Event Grid | NuGet [1.0.0](https://www.nuget.org/packages/Microsoft.Azure.Messaging.EventGrid.CloudNativeCloudEvents/1.0.0) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.Messaging.EventGrid.CloudNativeCloudEvents-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.Messaging.EventGrid.CloudNativeCloudEvents_1.0.0/sdk/eventgrid/Microsoft.Azure.Messaging.EventGrid.CloudNativeCloudEvents/) |
| Core - Client - Spatial | NuGet [1.1.0](https://www.nuget.org/packages/Microsoft.Azure.Core.Spatial/1.1.0)<br>NuGet [1.2.0-beta.1](https://www.nuget.org/packages/Microsoft.Azure.Core.Spatial/1.2.0-beta.1) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.Core.Spatial-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.Core.Spatial_1.1.0/sdk/core/Microsoft.Azure.Core.Spatial/)<br>GitHub [1.2.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.Core.Spatial_1.2.0-beta.1/sdk/core/Microsoft.Azure.Core.Spatial/) |
Expand Down
1 change: 1 addition & 0 deletions docs/core/compatibility/10.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ If you're migrating an app to .NET 10, the breaking changes listed here might af
| Title | Type of change |
|-------|---------------------|
| [BackgroundService runs all of ExecuteAsync as a Task](extensions/10.0/backgroundservice-executeasync-task.md) | Behavioral change |
| [Fix issues in GetKeyedService() and GetKeyedServices() with AnyKey](extensions/10.0/getkeyedservice-anykey.md) | Behavioral change |
| [Null values preserved in configuration](extensions/10.0/configuration-null-values-preserved.md) | Behavioral change |
| [Message no longer duplicated in Console log output](extensions/10.0/console-json-logging-duplicate-messages.md) | Behavioral change |
| [ProviderAliasAttribute moved to Microsoft.Extensions.Logging.Abstractions assembly](extensions/10.0/provideraliasattribute-moved-assembly.md) | Source incompatible |
Expand Down
Loading
Loading