Skip to content

Conversation

mokarchi
Copy link

@mokarchi mokarchi commented Sep 18, 2025

This PR implements enhanced dependency injection support for the OpenAI .NET library, addressing the feature request for built-in extension methods for IServiceCollection. The implementation follows .NET ecosystem standards similar to Azure SDKs, making it easier to integrate OpenAI clients into ASP.NET Core, Blazor, and other .NET applications.

Key Features Added

Extension Methods for IServiceCollection

The library now provides convenient extension methods for registering OpenAI clients:

using OpenAI.Extensions.DependencyInjection;

// Register individual clients with API key
builder.Services.AddOpenAIChat("gpt-4o", "your-api-key");
builder.Services.AddOpenAIEmbeddings("text-embedding-3-small");

// Register the main OpenAI client factory
builder.Services.AddOpenAI("your-api-key");
builder.Services.AddOpenAIChat("gpt-4o"); // Uses the registered OpenAIClient

Configuration Integration

Full support for IConfiguration binding with appsettings.json:

{
  "OpenAI": {
    "ApiKey": "your-api-key",
    "DefaultChatModel": "gpt-4o",
    "DefaultEmbeddingModel": "text-embedding-3-small",
    "Endpoint": "https://api.openai.com/v1",
    "OrganizationId": "your-org-id"
  }
}
// Register services from configuration
builder.Services.AddOpenAIFromConfiguration(builder.Configuration);

// Add specific clients using default models from configuration
builder.Services.AddChatClientFromConfiguration();
builder.Services.AddEmbeddingClientFromConfiguration();

// Or add all common clients at once
builder.Services.AddAllOpenAIClientsFromConfiguration();

Environment Variable Support

Automatic fallback to the OPENAI_API_KEY environment variable for development scenarios:

// This will use the OPENAI_API_KEY environment variable if no API key is provided
builder.Services.AddOpenAIChat("gpt-4o");

Implementation Details

Available Extension Methods

  • Core Registration: AddOpenAI(), AddOpenAIChat(), AddOpenAIEmbeddings(), AddOpenAIAudio(), AddOpenAIImages(), AddOpenAIModeration()
  • Configuration-Based: AddOpenAIFromConfiguration(), AddChatClientFromConfiguration(), etc.
  • Bulk Registration: AddAllOpenAIClientsFromConfiguration()

Enhanced Configuration Options

The new OpenAIServiceOptions class extends OpenAIClientOptions with DI-specific settings:

  • Default model configurations for each client type
  • API key configuration with environment variable fallback
  • All existing OpenAIClientOptions properties (Endpoint, OrganizationId, ProjectId, etc.)

Thread-Safe Singleton Registration

All clients are registered as singletons by default, following the existing recommendation in the README. This maximizes resource efficiency and HTTP connection reuse while maintaining thread safety.

Backward Compatibility

This implementation is fully backward compatible. Existing manual registration patterns continue to work unchanged:

// Existing manual registration still works
builder.Services.AddSingleton<ChatClient>(serviceProvider =>
{
    var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY");
    return new ChatClient("gpt-4o", apiKey);
});

This commit introduces new features for dependency injection in the OpenAI .NET library, allowing for easier registration and configuration of clients within ASP.NET Core applications. Key changes include:

- New extension methods for registering OpenAI clients with support for `appsettings.json` and environment variables.
- Introduction of the `OpenAIServiceOptions` class for simplified configuration.
- Updates to README.md with detailed usage instructions and examples.
- Modifications to project files to include necessary package references.
- Comprehensive unit tests to validate the new features and ensure proper functionality.
@stephentoub
Copy link
Contributor

Should this instead be left to Aspire, e.g. https://www.nuget.org/packages/Aspire.OpenAI ?

cc: @eerhardt

@KrzysztofCwalina
Copy link
Collaborator

I also think configuration like this needs to be aligned with what we already have in both Aspire, .NET, and Azure. In fact, I had a sync up with @eerhardt a couple of days ago to design a consistent solution.

cc @m-nash

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants