> For the complete documentation index, see [llms.txt](https://docs.flexbase.in/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flexbase.in/data-and-providers/providers.md).

# Providers

FlexBase provides unified abstractions for external service providers, enabling you to switch implementations without changing application code. All providers follow consistent patterns for configuration, usage, and error handling.

## Available Providers

### Communication Providers

| Provider Type                                                          | Description                        | Use Cases                                 |
| ---------------------------------------------------------------------- | ---------------------------------- | ----------------------------------------- |
| [**AI Providers**](/data-and-providers/providers/ai-providers.md)      | LLM chat, embeddings, streaming    | RAG, semantic search, content generation  |
| [**Email Providers**](/data-and-providers/providers/e-mail.md)         | Transactional and templated emails | Notifications, password resets, receipts  |
| [**Message Providers**](/data-and-providers/providers/text-message.md) | SMS, push, chat platforms          | Verification codes, alerts, notifications |

### AI Providers

Connect to multiple AI/LLM services with one interface:

| Provider             | Best For               | Features                          |
| -------------------- | ---------------------- | --------------------------------- |
| **Azure OpenAI**     | Enterprise, compliance | GPT-4o, embeddings, SLA           |
| **OpenAI**           | Latest models          | GPT-4o, o1, latest features       |
| **Anthropic Claude** | Long context, analysis | 200K context, reasoning           |
| **Google Gemini**    | Multimodal             | Text, images, competitive pricing |
| **Ollama**           | Local/offline          | Privacy, no API costs             |

```csharp
// Works with ANY AI provider
public class ChatService
{
    private readonly IFlexAIProvider _aiProvider;  // Could be OpenAI, Claude, Ollama, etc.
    
    public async Task<string> AskAsync(string question)
    {
        return await _aiProvider.ChatAsync(question);
    }
}
```

### Email Providers

Send emails through multiple services:

| Provider             | Best For         | Features                       |
| -------------------- | ---------------- | ------------------------------ |
| **Console**          | Development      | No real emails, console output |
| **SMTP**             | Standard servers | Office 365, Gmail, custom      |
| **SMTP + Templates** | Branded emails   | Built-in templates, variables  |
| **SendGrid**         | Transactional    | Delivery tracking, analytics   |

```csharp
// Works with ANY email provider
public class NotificationService
{
    private readonly IFlexEmailProvider _emailProvider;
    
    public async Task SendWelcomeAsync(string email, string name)
    {
        await _emailProvider.SendTemplatedAsync(
            to: email,
            templateId: "welcome",
            templateData: new Dictionary<string, object>
            {
                ["userName"] = name,
                ["loginUrl"] = "https://app.example.com"
            }
        );
    }
}
```

### Message Providers

Send messages across multiple channels:

| Channel         | Use Cases                  | Providers         |
| --------------- | -------------------------- | ----------------- |
| **SMS**         | Verification codes, alerts | Twilio, AWS SNS   |
| **Push**        | Mobile notifications       | Firebase, AWS SNS |
| **WhatsApp**    | Customer support           | Twilio            |
| **Slack/Teams** | Internal alerts            | Native APIs       |
| **Console**     | Development                | Testing           |

```csharp
// Multi-channel messaging
public class AlertService
{
    private readonly IFlexTextMessageProvider _messageProvider;

	public AlertService(IFlexTextMessageProvider messageProvider)
		=> _messageProvider = messageProvider;
    
    public async Task SendAlertAsync(User user, string message)
    {
        // SMS
        if (!string.IsNullOrEmpty(user.PhoneNumber))
        {
            await _messageProvider.SendSmsAsync(user.PhoneNumber, message);
        }
        
        // Push notification
        if (!string.IsNullOrEmpty(user.DeviceToken))
        {
            await _messageProvider.SendPushAsync(
                user.DeviceToken,
                "Alert",
                message
            );
        }
    }
}
```

## Common Patterns

### Automatic Setup via Flex Studio

Providers are automatically added to your application through **Flex Studio**. When you add a provider:

1. **Provider files are created** in `Infrastructure/Providers/{YourApplication}.DataStoreProviders/{Category}/{Provider}/`
2. **NuGet package is referenced** automatically
3. **Default configuration** is added to `Application/EndPoints/{YourApplication}.EndPoint.CommonConfigs/AppSettings/{Category}/{Provider}.json`
4. **README documentation** is included in the provider folder

You can find all provider files, configuration examples, and documentation in the generated infrastructure folder.

### Configuration

Providers use the IOptions pattern. Configuration files are automatically created when you add providers via Flex Studio:

```json
{
    "FlexBase": {
      "AI": {
        "OpenAI": {
          "ApiKey": "<store-in-secrets>",
          "DefaultChatModel": "gpt-4o"
        }
      },
      "Providers": {
        "Email": {
          "Smtp": {
            "Host": "smtp.office365.com",
            "Port": 587,
            "Username": "user@company.com",
            "Password": "<store-in-secrets>"
          }
        },
        "Message": {
          "Console": {
            "DefaultChannel": "Sms"
          }
        }
      }
    }
}
```

Configuration files are located at:

* `Application/EndPoints/{YourApplication}.EndPoint.CommonConfigs/AppSettings/AI/{Provider}.json`
* `Application/EndPoints/{YourApplication}.EndPoint.CommonConfigs/AppSettings/Email/{Provider}.json`
* `Application/EndPoints/{YourApplication}.EndPoint.CommonConfigs/AppSettings/Message/{Provider}.json`

### Dependency Injection

After adding providers via Flex Studio, register only the provider in `Program.cs` (the generated queries/handlers/plugins are auto-wired by Flex):

```csharp
// AI provider
builder.Services.AddFlexOpenAI(builder.Configuration);

// Email provider
builder.Services.AddFlexSmtpEmailProvider(builder.Configuration);

// Message provider
builder.Services.AddFlexConsoleMessageProvider(builder.Configuration);
```

### Multiple Providers

Use keyed services (.NET 8+) for multiple providers:

```csharp
// Register multiple AI providers
builder.Services.AddKeyedSingleton<IFlexAIProvider>("openai", (sp, _) =>
    new FlexOpenAIProvider(Configuration["OpenAI:ApiKey"]!));

builder.Services.AddKeyedSingleton<IFlexAIProvider>("local", (sp, _) =>
    new OllamaProvider());

// Use in service
public class AIService
{
    private readonly IFlexAIProvider _cloud;
    private readonly IFlexAIProvider _local;

    public AIService(
        [FromKeyedServices("openai")] IFlexAIProvider cloud,
        [FromKeyedServices("local")] IFlexAIProvider local)
    {
        _cloud = cloud;
        _local = local;
    }

    public async Task<string> ProcessAsync(string input, bool useLocal = false)
    {
        var provider = useLocal ? _local : _cloud;
        return await provider.ChatAsync(input);
    }
}
```

## Provider-Agnostic Benefits

### 1. Easy Testing

Use console/mock providers during development:

```csharp
// Development
builder.Services.AddFlexConsoleEmailProvider();
builder.Services.AddFlexConsoleMessageProvider();

// Production
builder.Services.AddFlexSmtpEmailProvider();
builder.Services.AddTwilioMessageProvider();
```

### 2. Cost Optimization

Switch providers based on cost or features:

```csharp
public class CostOptimizedService
{
    private readonly IFlexAIProvider _cloudProvider;   // GPT-4o for complex
    private readonly IFlexAIProvider _localProvider;   // Ollama for simple

    public async Task<string> ProcessAsync(string input)
    {
        if (IsComplexQuery(input))
        {
            return await _cloudProvider.ChatAsync(input);
        }
        else
        {
            return await _localProvider.ChatAsync(input);  // Free!
        }
    }
}
```

### 3. Vendor Independence

Avoid vendor lock-in - switch providers with configuration:

```csharp
// Application code stays the same
public class MyService
{
    private readonly IFlexAIProvider _ai;
    private readonly IFlexEmailProvider _email;
    
    // Works with ANY provider implementation
}
```

## Error Handling

All providers follow consistent error patterns:

```csharp
public async Task<bool> SendWithErrorHandlingAsync()
{
    try
    {
        var result = await _provider.SendAsync(message);
        
        if (!result.IsSuccess)
        {
            _logger.LogError("Operation failed: {Error}", result.ErrorMessage);
            
            // Handle specific error codes
            switch (result.ErrorCode)
            {
                case "RATE_LIMITED":
                    await Task.Delay(TimeSpan.FromSeconds(5));
                    return await SendWithErrorHandlingAsync();  // Retry
                
                case "INVALID_INPUT":
                    return false;  // Don't retry
                
                default:
                    throw new Exception(result.ErrorMessage);
            }
        }
        
        return true;
    }
    catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.Unauthorized)
    {
        _logger.LogError("Invalid credentials");
        throw;
    }
}
```

## Best Practices

### 1. Use Console Providers in Development

```csharp
if (builder.Environment.IsDevelopment())
{
    builder.Services.AddFlexConsoleEmailProvider();
    builder.Services.AddFlexConsoleMessageProvider();
    builder.Services.AddSingleton<IFlexAIProvider>(new OllamaProvider());
}
else
{
    builder.Services.AddFlexSmtpEmailProvider(/* production config */);
    builder.Services.AddTwilioMessageProvider(/* production config */);
    builder.Services.AddSingleton<IFlexAIProvider>(new FlexOpenAIProvider(/* production config */));
}
```

### 2. Validate Configuration on Startup

```csharp
// In Program.cs after building
using var scope = app.Services.CreateScope();

var aiProvider = scope.ServiceProvider.GetRequiredService<IFlexAIProvider>();
if (!await aiProvider.TestConnectionAsync())
{
    throw new InvalidOperationException("AI provider not configured correctly");
}

var emailProvider = scope.ServiceProvider.GetRequiredService<IFlexEmailProvider>();
if (!await emailProvider.TestConnectionAsync())
{
    throw new InvalidOperationException("Email provider not configured correctly");
}
```

### 3. Implement Retry Logic

```csharp
public async Task<T> ExecuteWithRetryAsync<T>(
    Func<Task<T>> operation,
    int maxRetries = 3)
{
    for (int attempt = 1; attempt <= maxRetries; attempt++)
    {
        try
        {
            return await operation();
        }
        catch (Exception ex) when (attempt < maxRetries)
        {
            _logger.LogWarning(
                "Attempt {Attempt}/{Max} failed: {Error}",
                attempt, maxRetries, ex.Message
            );
            
            await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)));
        }
    }
    
    throw new InvalidOperationException("All retry attempts failed");
}
```

### 4. Monitor and Log

```csharp
public async Task<string> MonitoredChatAsync(string message)
{
    var stopwatch = Stopwatch.StartNew();
    
    try
    {
        var response = await _aiProvider.ChatAsync(message);
        
        _logger.LogInformation(
            "AI chat completed in {ElapsedMs}ms. Provider: {Provider}, Tokens: {Tokens}",
            stopwatch.ElapsedMilliseconds,
            _aiProvider.Provider,
            response.Usage?.TotalTokens
        );
        
        return response.Message.Content;
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "AI chat failed after {ElapsedMs}ms", stopwatch.ElapsedMilliseconds);
        throw;
    }
}
```

## Integration Examples

### AI + Vector Store (RAG)

```csharp
public class RAGService
{
    private readonly IFlexAIProvider _aiProvider;
    private readonly IFlexVectorStore _vectorStore;

    public async Task<string> AskAsync(string question)
    {
        // 1. Generate embedding
        var queryEmbedding = await _aiProvider.EmbedAsync(question);

        // 2. Search vector store
        var results = await _vectorStore.SearchAsync(queryEmbedding, topK: 5);

        // 3. Build context
        var context = string.Join("\n\n", results.Select(r => r.Content));

        // 4. Get AI response
        return await _aiProvider.ChatAsync($"Context: {context}\n\nQuestion: {question}");
    }
}
```

### Email + Message (Multi-Channel Notifications)

```csharp
public class NotificationService
{
    private readonly IFlexEmailProvider _emailProvider;
    private readonly IFlexTextMessageProvider _messageProvider;

    public NotificationService(IFlexEmailProvider emailProvider, IFlexTextMessageProvider messageProvider)
    {
        _emailProvider = emailProvider;
        _messageProvider = messageProvider;
    }

    public async Task NotifyUserAsync(User user, string message)
    {
        var tasks = new List<Task>();

        // Email
        if (!string.IsNullOrEmpty(user.Email))
        {
            tasks.Add(_emailProvider.SendAsync(user.Email, "Notification", message));
        }

        // SMS
        if (!string.IsNullOrEmpty(user.PhoneNumber))
        {
            tasks.Add(_messageProvider.SendSmsAsync(user.PhoneNumber, message));
        }

        // Push
        if (!string.IsNullOrEmpty(user.DeviceToken))
        {
            tasks.Add(_messageProvider.SendPushAsync(user.DeviceToken, "Notification", message));
        }

        await Task.WhenAll(tasks);
    }
}
```

## Advanced Usage Examples

### AI Providers

AI providers enable seamless integration with various LLM services. Below is an example of using an AI provider for generating responses:

```csharp
public class AIResponseService
{
    private readonly IFlexAIProvider _aiProvider;

    public AIResponseService(IFlexAIProvider aiProvider)
    {
        _aiProvider = aiProvider;
    }

    public async Task<string> GenerateResponseAsync(string prompt)
    {
        return await _aiProvider.ChatAsync(prompt);
    }
}
```

### Email Providers

Email providers support sending templated and transactional emails. Below is an example:

```csharp
public class EmailNotificationService
{
    private readonly IFlexEmailProvider _emailProvider;

    public EmailNotificationService(IFlexEmailProvider emailProvider)
    {
        _emailProvider = emailProvider;
    }

    public async Task SendPasswordResetAsync(string email, string resetLink)
    {
        await _emailProvider.SendTemplatedAsync(
            to: email,
            templateId: "password_reset",
            templateData: new Dictionary<string, object>
            {
                ["resetLink"] = resetLink
            }
        );
    }
}
```

### Message Providers

Message providers allow sending SMS, push notifications, and more. Below is an example:

```csharp
public class SmsService
{
    private readonly IFlexTextMessageProvider _messageProvider;

    public SmsService(IFlexTextMessageProvider messageProvider)
    {
        _messageProvider = messageProvider;
    }

    public async Task SendVerificationCodeAsync(string phoneNumber, string code)
    {
        await _messageProvider.SendAsync(new FlexTextMessage
        {
            Channel = FlexMessageChannel.Sms,
			Recipients = new List<string> { phoneNumber },
            Content = $"Your verification code is {code}."
        });
    }
}
```

## See Also

* [Data Stores](/data-and-providers/data-stores.md) - Vector, search, document stores
* [Relational Databases](/data-and-providers/relational-db.md) - EF Core and Dapper
* [AI Providers Details](/data-and-providers/providers/ai-providers.md) - Complete AI provider documentation
* [Email Providers Details](/data-and-providers/providers/e-mail.md) - Complete email provider documentation
* [Message Providers Details](/data-and-providers/providers/text-message.md) - Complete message provider documentation
