ASP.NET Core  

ASP.NET Core Cloud Domination: Master Azure & AWS Global Scaling, Storage & Hosting | Production Guide (Part-25 of 40)

 

cloud

Previous article: AI Integration Boom: Infusing ASP.NET Core with ML.NET & OpenAI (Part-24 of 40)

Table of Contents

  1. Introduction to Cloud-Native ASP.NET Core

  2. Azure Cloud Services Deep Dive

  3. AWS Cloud Integration Mastery

  4. Global Scaling Strategies

  5. Cloud Storage Solutions

  6. Microservices in Cloud

  7. Production Deployment Patterns

  8. Real-World Case Study

  9. Best Practices & Optimization

1. Introduction to Cloud-Native ASP.NET Core

1.1 What is Cloud-Native Development?

Cloud-native development represents a paradigm shift in how we build, deploy, and scale applications. Unlike traditional approaches, cloud-native applications are designed from the ground up to leverage cloud infrastructure, enabling unprecedented scalability, resilience, and flexibility.

Key Characteristics:

  • Microservices architecture

  • Containerization

  • Dynamic orchestration

  • DevOps continuous delivery

  • Infrastructure as code

1.2 Why ASP.NET Core for Cloud?

ASP.NET Core has evolved into the perfect framework for cloud-native development:

  
    // Program.cs - Modern ASP.NET Core cloud-ready setup
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using Azure.Identity;
using Amazon.Extensions.NETCore.Setup;

var builder = WebApplication.CreateBuilder(args);

// Cloud-optimized configuration
builder.Configuration
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
    .AddEnvironmentVariables()  // Critical for cloud deployment
    .AddUserSecrets<Program>()  // For local development
    .AddAzureKeyVault(          // For production secrets
        new Uri(builder.Configuration["KeyVault:Endpoint"]),
        new DefaultAzureCredential());

// Cloud-optimized services
builder.Services.AddControllers();
builder.Services.AddHealthChecks();  // Essential for cloud monitoring
builder.Services.AddApplicationInsightsTelemetry();

// Configure for cloud scalability
builder.Services.Configure<HostOptions>(options =>
{
    options.ShutdownTimeout = TimeSpan.FromSeconds(30);  // Graceful shutdown
});

var app = builder.Build();

// Cloud-specific middleware pipeline
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Error");  // Production error handling
    app.UseHsts();  // HTTP Strict Transport Security
}

app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();

// Health check endpoint for cloud load balancers
app.MapHealthChecks("/health");
app.MapControllers();

await app.RunAsync();
  

1.3 Real-World Business Impact

Scenario : E-commerce Platform Scaling for Holiday Season

Imagine an e-commerce platform that normally handles 10,000 daily users but needs to scale to 1,000,000 users during Black Friday sales. Traditional infrastructure would collapse under this load, but cloud-native ASP.NET Core applications can scale dynamically.

  
    // Startup configuration for auto-scaling
public void ConfigureServices(IServiceCollection services)
{
    // Configure for horizontal scaling
    services.AddDistributedMemoryCache();  // Use Redis in production
    
    // Stateless design for scale-out
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });
    
    // Add session with distributed cache support
    services.AddSession(options =>
    {
        options.Cookie.HttpOnly = true;
        options.Cookie.IsEssential = true;
        options.IdleTimeout = TimeSpan.FromMinutes(20);
    });
}
  

2. Azure Cloud Services Deep Dive

2.1 Azure App Service for ASP.NET Core

Azure App Service provides fully managed platform for deploying web applications with built-in scaling, security, and monitoring.

2.1.1 Deployment Configuration

appsettings.json for Azure

  
    {
  "Azure": {
    "AppService": {
      "InstanceId": "{WEBSITE_INSTANCE_ID}",
      "SKU": "{WEBSITE_SKU}",
      "ResourceGroup": "{WEBSITE_RESOURCE_GROUP}"
    }
  },
  "ConnectionStrings": {
    "AzureSQL": "Server=tcp:{server}.database.windows.net;Database={db};User ID={user};Password={password};Trusted_Connection=False;Encrypt=True;"
  },
  "ApplicationInsights": {
    "InstrumentationKey": "{your_instrumentation_key}"
  }
}
  

2.1.2 Program.cs Configuration for Azure

  
    using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Azure.Identity;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((context, config) =>
            {
                var builtConfig = config.Build();
                
                // Azure App Configuration for centralized configuration management
                if (!context.HostingEnvironment.IsDevelopment())
                {
                    config.AddAzureAppConfiguration(options =>
                    {
                        options.Connect(builtConfig["ConnectionStrings:AppConfig"])
                               .ConfigureKeyVault(kv =>
                               {
                                   kv.SetCredential(new DefaultAzureCredential());
                               });
                    });
                }
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
                
                // Azure-specific configurations
                webBuilder.ConfigureKestrel(serverOptions =>
                {
                    serverOptions.Limits.MaxRequestBodySize = 52428800; // 50MB
                    serverOptions.Limits.MaxConcurrentConnections = 100;
                    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
                });
            })
            .UseAzureAppServices()  // Azure-specific logging and diagnostics
            .ConfigureLogging((context, logging) =>
            {
                logging.AddAzureWebAppDiagnostics();
            });
}
  

2.1.3 Advanced Azure Deployment with Bicep

main.bicep - Infrastructure as Code:

  
    param location string = 'eastus'
param appName string = 'my-aspnet-app'
param skuName string = 'S1'
param skuCapacity int = 2

resource appServicePlan 'Microsoft.Web/serverfarms@2021-03-01' = {
  name: 'plan-${appName}'
  location: location
  sku: {
    name: skuName
    capacity: skuCapacity
  }
  properties: {
    reserved: true
  }
}

resource webApp 'Microsoft.Web/sites@2021-03-01' = {
  name: appName
  location: location
  properties: {
    serverFarmId: appServicePlan.id
    siteConfig: {
      netFrameworkVersion: 'v6.0'
      alwaysOn: true
      appSettings: [
        {
          name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
          value: appInsights.properties.InstrumentationKey
        }
      ]
    }
    httpsOnly: true
  }
  identity: {
    type: 'SystemAssigned'
  }
}

resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
  name: 'ai-${appName}'
  location: location
  properties: {
    Application_Type: 'web'
    Flow_Type: 'Bluefield'
  }
}
  

2.2 Azure SQL Database Integration

2.2.1 Entity Framework Core with Azure SQL

  
    // DataContext.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;

public class ApplicationDbContext : DbContext
{
    private readonly IConfiguration _configuration;

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, 
                              IConfiguration configuration) 
        : base(options)
    {
        _configuration = configuration;
    }

    public DbSet<Product> Products { get; set; }
    public DbSet<Order> Orders { get; set; }
    public DbSet<Customer> Customers { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            // Use retry logic for cloud database
            optionsBuilder.UseSqlServer(
                _configuration.GetConnectionString("AzureSQL"),
                options => 
                {
                    options.EnableRetryOnFailure(
                        maxRetryCount: 5,
                        maxRetryDelay: TimeSpan.FromSeconds(30),
                        errorNumbersToAdd: null);
                });
        }
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Configure for cloud performance
        modelBuilder.Entity<Product>(entity =>
        {
            entity.HasKey(e => e.Id);
            entity.HasIndex(e => e.CategoryId);  // Important for query performance
            entity.Property(e => e.Price).HasColumnType("decimal(18,2)");
        });

        // Configure soft delete pattern
        modelBuilder.Entity<Customer>(entity =>
        {
            entity.HasQueryFilter(e => !e.IsDeleted);
        });
    }
}

// Startup configuration
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>((serviceProvider, options) =>
    {
        var configuration = serviceProvider.GetRequiredService<IConfiguration>();
        options.UseSqlServer(
            configuration.GetConnectionString("AzureSQL"),
            sqlOptions =>
            {
                sqlOptions.EnableRetryOnFailure(
                    maxRetryCount: 5,
                    maxRetryDelay: TimeSpan.FromSeconds(30),
                    errorNumbersToAdd: null);
            });
    });
}
  

2.2.2 Database Resilience with Polly

  
    // DatabaseResilienceService.cs
using Polly;
using Polly.Retry;
using System.Data.SqlClient;

public class DatabaseResilienceService
{
    private readonly AsyncRetryPolicy _retryPolicy;
    private readonly ILogger<DatabaseResilienceService> _logger;

    public DatabaseResilienceService(ILogger<DatabaseResilienceService> logger)
    {
        _logger = logger;
        
        _retryPolicy = Policy
            .Handle<SqlException>(ex => IsTransientError(ex))
            .Or<TimeoutException>()
            .WaitAndRetryAsync(
                retryCount: 3,
                sleepDurationProvider: retryAttempt => 
                    TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
                onRetry: (exception, timeSpan, retryCount, context) =>
                {
                    _logger.LogWarning(exception, 
                        $"Database operation failed. Retrying attempt {retryCount} after {timeSpan.TotalSeconds}s.");
                });
    }

    public async Task<T> ExecuteWithResilienceAsync<T>(Func<Task<T>> operation)
    {
        return await _retryPolicy.ExecuteAsync(operation);
    }

    private bool IsTransientError(SqlException ex)
    {
        // SQL Server transient error numbers
        int[] transientErrors = { 4060, 40197, 40501, 40613, 
                                49918, 49919, 49920, 11001 };
        return transientErrors.Contains(ex.Number);
    }
}

// Usage in repository
public class ProductRepository
{
    private readonly ApplicationDbContext _context;
    private readonly DatabaseResilienceService _resilienceService;

    public ProductRepository(ApplicationDbContext context, 
                           DatabaseResilienceService resilienceService)
    {
        _context = context;
        _resilienceService = resilienceService;
    }

    public async Task<List<Product>> GetProductsByCategoryAsync(int categoryId)
    {
        return await _resilienceService.ExecuteWithResilienceAsync(async () =>
        {
            return await _context.Products
                .Where(p => p.CategoryId == categoryId && p.IsActive)
                .OrderBy(p => p.Name)
                .ToListAsync();
        });
    }
}
  

2.3 Azure Storage Integration

2.3.1 Blob Storage for File Management

  
    // AzureBlobStorageService.cs
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Microsoft.Extensions.Configuration;

public interface IFileStorageService
{
    Task<string> UploadFileAsync(Stream fileStream, string fileName, string contentType);
    Task<Stream> DownloadFileAsync(string fileName);
    Task<bool> DeleteFileAsync(string fileName);
    Task<List<string>> ListFilesAsync(string prefix = null);
}

public class AzureBlobStorageService : IFileStorageService
{
    private readonly BlobServiceClient _blobServiceClient;
    private readonly string _containerName;
    private readonly ILogger<AzureBlobStorageService> _logger;

    public AzureBlobStorageService(IConfiguration configuration, 
                                  ILogger<AzureBlobStorageService> logger)
    {
        var connectionString = configuration.GetConnectionString("AzureStorage");
        _blobServiceClient = new BlobServiceClient(connectionString);
        _containerName = configuration["AzureStorage:ContainerName"] ?? "default";
        _logger = logger;
        
        InitializeContainerAsync().GetAwaiter().GetResult();
    }

    private async Task InitializeContainerAsync()
    {
        try
        {
            var containerClient = _blobServiceClient.GetBlobContainerClient(_containerName);
            await containerClient.CreateIfNotExistsAsync(PublicAccessType.None);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to initialize blob container");
            throw;
        }
    }

    public async Task<string> UploadFileAsync(Stream fileStream, string fileName, string contentType)
    {
        try
        {
            var containerClient = _blobServiceClient.GetBlobContainerClient(_containerName);
            var blobClient = containerClient.GetBlobClient(fileName);

            await blobClient.UploadAsync(fileStream, new BlobHttpHeaders 
            { 
                ContentType = contentType 
            });

            return blobClient.Uri.ToString();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to upload file: {fileName}");
            throw;
        }
    }

    public async Task<Stream> DownloadFileAsync(string fileName)
    {
        try
        {
            var containerClient = _blobServiceClient.GetBlobContainerClient(_containerName);
            var blobClient = containerClient.GetBlobClient(fileName);

            var response = await blobClient.DownloadAsync();
            return response.Value.Content;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to download file: {fileName}");
            throw;
        }
    }

    public async Task<bool> DeleteFileAsync(string fileName)
    {
        try
        {
            var containerClient = _blobServiceClient.GetBlobContainerClient(_containerName);
            var blobClient = containerClient.GetBlobClient(fileName);
            
            return await blobClient.DeleteIfExistsAsync();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to delete file: {fileName}");
            throw;
        }
    }

    public async Task<List<string>> ListFilesAsync(string prefix = null)
    {
        var fileNames = new List<string>();
        var containerClient = _blobServiceClient.GetBlobContainerClient(_containerName);

        await foreach (var blobItem in containerClient.GetBlobsAsync(prefix: prefix))
        {
            fileNames.Add(blobItem.Name);
        }

        return fileNames;
    }
}

// Controller usage
[ApiController]
[Route("api/[controller]")]
public class FilesController : ControllerBase
{
    private readonly IFileStorageService _fileStorageService;
    private readonly ILogger<FilesController> _logger;

    public FilesController(IFileStorageService fileStorageService, 
                         ILogger<FilesController> logger)
    {
        _fileStorageService = fileStorageService;
        _logger = logger;
    }

    [HttpPost("upload")]
    public async Task<IActionResult> UploadFile(IFormFile file)
    {
        if (file == null || file.Length == 0)
            return BadRequest("No file uploaded");

        try
        {
            using var stream = file.OpenReadStream();
            var fileUrl = await _fileStorageService.UploadFileAsync(
                stream, 
                Guid.NewGuid().ToString() + Path.GetExtension(file.FileName),
                file.ContentType);

            return Ok(new { FileUrl = fileUrl });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "File upload failed");
            return StatusCode(500, "File upload failed");
        }
    }

    [HttpGet("download/{fileName}")]
    public async Task<IActionResult> DownloadFile(string fileName)
    {
        try
        {
            var stream = await _fileStorageService.DownloadFileAsync(fileName);
            return File(stream, "application/octet-stream", fileName);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"File download failed: {fileName}");
            return NotFound();
        }
    }
}
  

2.3.2 Table Storage for NoSQL Data

  
    // AzureTableStorageService.cs
using Azure.Data.Tables;
using Microsoft.Extensions.Configuration;

public class AzureTableStorageService<T> where T : class, ITableEntity, new()
{
    private readonly TableServiceClient _tableServiceClient;
    private readonly TableClient _tableClient;
    private readonly string _tableName;
    private readonly ILogger<AzureTableStorageService<T>> _logger;

    public AzureTableStorageService(IConfiguration configuration, 
                                   ILogger<AzureTableStorageService<T>> logger)
    {
        var connectionString = configuration.GetConnectionString("AzureStorage");
        _tableServiceClient = new TableServiceClient(connectionString);
        _tableName = typeof(T).Name.ToLower() + "s";
        _tableClient = _tableServiceClient.GetTableClient(_tableName);
        _logger = logger;
        
        InitializeTableAsync().GetAwaiter().GetResult();
    }

    private async Task InitializeTableAsync()
    {
        try
        {
            await _tableClient.CreateIfNotExistsAsync();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to initialize table: {_tableName}");
            throw;
        }
    }

    public async Task<T> GetEntityAsync(string partitionKey, string rowKey)
    {
        try
        {
            var response = await _tableClient.GetEntityAsync<T>(partitionKey, rowKey);
            return response.Value;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to get entity: {partitionKey}/{rowKey}");
            return null;
        }
    }

    public async Task UpsertEntityAsync(T entity)
    {
        try
        {
            await _tableClient.UpsertEntityAsync(entity);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to upsert entity");
            throw;
        }
    }

    public async Task DeleteEntityAsync(string partitionKey, string rowKey)
    {
        try
        {
            await _tableClient.DeleteEntityAsync(partitionKey, rowKey);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to delete entity: {partitionKey}/{rowKey}");
            throw;
        }
    }

    public async Task<List<T>> QueryEntitiesAsync(string filter = null)
    {
        var entities = new List<T>();
        
        try
        {
            var query = _tableClient.QueryAsync<T>(filter);
            await foreach (var entity in query)
            {
                entities.Add(entity);
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to query entities");
            throw;
        }

        return entities;
    }
}

// Example entity
public class UserSession : ITableEntity
{
    public string PartitionKey { get; set; }  // UserId
    public string RowKey { get; set; }        // SessionId
    public DateTimeOffset? Timestamp { get; set; }
    public Azure.ETag ETag { get; set; }
    
    public string UserName { get; set; }
    public DateTime LoginTime { get; set; }
    public DateTime LastActivity { get; set; }
    public string IpAddress { get; set; }
}
  

3. AWS Cloud Integration Mastery

3.1 AWS Elastic Beanstalk for ASP.NET Core

AWS Elastic Beanstalk provides an easy-to-use service for deploying and scaling web applications.

3.1.1 AWS Configuration and Deployment

aws-beanstalk.config

  
    option_settings:
  aws:elasticbeanstalk:application:environment:
    ASPNETCORE_ENVIRONMENT: Production
    AWS_ACCESS_KEY_ID: your-access-key
    AWS_SECRET_ACCESS_KEY: your-secret-key
  aws:elasticbeanstalk:container:dotnet:app:
    AppPath: /var/app/current
  aws:elasticbeanstalk:cloudwatch:logs:
    StreamLogs: true
    RetentionInDays: 30
  aws:elasticbeanstalk:healthreporting:system:
    SystemType: enhanced

packages:
  yum:
    nginx: []
    dotnet8: []

files:
  "/etc/nginx/conf.d/proxy.conf":
    content: |
      client_max_body_size 50M;
  

3.1.2 Program.cs for AWS

  
    using Amazon;
using Amazon.Extensions.NETCore.Setup;
using Amazon.Runtime;
using Amazon.S3;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((context, config) =>
            {
                config.AddEnvironmentVariables();
                
                // AWS Systems Manager Parameter Store for configuration
                if (context.HostingEnvironment.IsProduction())
                {
                    var awsOptions = config.Build().GetAWSOptions();
                    config.AddSystemsManager("/my-app/production", awsOptions, 
                        TimeSpan.FromMinutes(5));
                }
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
                
                // AWS-specific configurations
                webBuilder.ConfigureKestrel(serverOptions =>
                {
                    serverOptions.Limits.MaxRequestBodySize = 52428800; // 50MB
                });
            })
            .ConfigureLogging((context, logging) =>
            {
                logging.AddAWSProvider();  // CloudWatch logging
                
                if (context.HostingEnvironment.IsDevelopment())
                {
                    logging.AddConsole();
                    logging.AddDebug();
                }
            })
            .UseDefaultServiceProvider((context, options) =>
            {
                options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
                options.ValidateOnBuild = true;
            });
}

// Startup configuration for AWS
public class Startup
{
    public Startup(IConfiguration configuration, IWebHostEnvironment environment)
    {
        Configuration = configuration;
        Environment = environment;
    }

    public IConfiguration Configuration { get; }
    public IWebHostEnvironment Environment { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        // AWS service configuration
        services.AddDefaultAWSOptions(Configuration.GetAWSOptions());
        services.AddAWSService<IAmazonS3>();
        
        services.AddControllersWithViews();
        
        // Health checks for AWS load balancer
        services.AddHealthChecks()
            .AddS3HealthCheck("s3-health-check")
            .AddDynamoDBHealthCheck("dynamodb-health-check");

        // AWS Cognito for authentication
        services.AddCognitoIdentity();
        
        // AWS X-Ray for distributed tracing
        services.AddXRay("my-aspnet-app");
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

        app.UseXRay("my-aspnet-app");
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthorization();
        
        // Health check endpoint for AWS load balancer
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapHealthChecks("/health");
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}
  

3.2 AWS S3 Integration

3.2.1 S3 File Storage Service

  
    // AWSS3StorageService.cs
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.S3.Transfer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

public interface IAwsFileStorageService
{
    Task<string> UploadFileAsync(Stream fileStream, string fileName, string contentType);
    Task<Stream> DownloadFileAsync(string fileName);
    Task<bool> DeleteFileAsync(string fileName);
    Task<List<S3Object>> ListFilesAsync(string prefix = null);
    Task<string> GeneratePresignedUrlAsync(string fileName, DateTime expiration);
}

public class AwsS3StorageService : IAwsFileStorageService
{
    private readonly IAmazonS3 _s3Client;
    private readonly string _bucketName;
    private readonly ILogger<AwsS3StorageService> _logger;

    public AwsS3StorageService(IAmazonS3 s3Client, IConfiguration configuration, 
                              ILogger<AwsS3StorageService> logger)
    {
        _s3Client = s3Client;
        _bucketName = configuration["AWS:S3:BucketName"] ?? "my-app-bucket";
        _logger = logger;
        
        InitializeBucketAsync().GetAwaiter().GetResult();
    }

    private async Task InitializeBucketAsync()
    {
        try
        {
            var bucketExists = await _s3Client.DoesS3BucketExistAsync(_bucketName);
            if (!bucketExists)
            {
                var putBucketRequest = new PutBucketRequest
                {
                    BucketName = _bucketName,
                    UseClientRegion = true
                };
                await _s3Client.PutBucketAsync(putBucketRequest);
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to initialize S3 bucket: {_bucketName}");
            throw;
        }
    }

    public async Task<string> UploadFileAsync(Stream fileStream, string fileName, string contentType)
    {
        try
        {
            var transferUtility = new TransferUtility(_s3Client);
            
            var uploadRequest = new TransferUtilityUploadRequest
            {
                InputStream = fileStream,
                Key = fileName,
                BucketName = _bucketName,
                ContentType = contentType,
                CannedACL = S3CannedACL.Private  // Security best practice
            };

            await transferUtility.UploadAsync(uploadRequest);
            
            return $"https://{_bucketName}.s3.amazonaws.com/{fileName}";
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to upload file to S3: {fileName}");
            throw;
        }
    }

    public async Task<Stream> DownloadFileAsync(string fileName)
    {
        try
        {
            var request = new GetObjectRequest
            {
                BucketName = _bucketName,
                Key = fileName
            };

            using var response = await _s3Client.GetObjectAsync(request);
            var memoryStream = new MemoryStream();
            await response.ResponseStream.CopyToAsync(memoryStream);
            memoryStream.Position = 0;
            
            return memoryStream;
        }
        catch (AmazonS3Exception ex) when (ex.ErrorCode == "NoSuchKey")
        {
            _logger.LogWarning($"File not found in S3: {fileName}");
            return null;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to download file from S3: {fileName}");
            throw;
        }
    }

    public async Task<bool> DeleteFileAsync(string fileName)
    {
        try
        {
            var deleteRequest = new DeleteObjectRequest
            {
                BucketName = _bucketName,
                Key = fileName
            };

            await _s3Client.DeleteObjectAsync(deleteRequest);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to delete file from S3: {fileName}");
            return false;
        }
    }

    public async Task<List<S3Object>> ListFilesAsync(string prefix = null)
    {
        try
        {
            var request = new ListObjectsV2Request
            {
                BucketName = _bucketName,
                Prefix = prefix
            };

            var response = await _s3Client.ListObjectsV2Async(request);
            return response.S3Objects;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to list files from S3");
            throw;
        }
    }

    public async Task<string> GeneratePresignedUrlAsync(string fileName, DateTime expiration)
    {
        try
        {
            var request = new GetPreSignedUrlRequest
            {
                BucketName = _bucketName,
                Key = fileName,
                Expires = expiration,
                Verb = HttpVerb.GET
            };

            return _s3Client.GetPreSignedURL(request);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to generate presigned URL for: {fileName}");
            throw;
        }
    }
}

// Controller for S3 operations
[ApiController]
[Route("api/[controller]")]
public class AwsFilesController : ControllerBase
{
    private readonly IAwsFileStorageService _fileStorageService;
    private readonly ILogger<AwsFilesController> _logger;

    public AwsFilesController(IAwsFileStorageService fileStorageService, 
                            ILogger<AwsFilesController> logger)
    {
        _fileStorageService = fileStorageService;
        _logger = logger;
    }

    [HttpPost("upload")]
    [RequestSizeLimit(50_000_000)]  // 50MB limit
    public async Task<IActionResult> UploadFile(IFormFile file)
    {
        if (file == null || file.Length == 0)
            return BadRequest("No file uploaded");

        try
        {
            using var stream = file.OpenReadStream();
            var fileUrl = await _fileStorageService.UploadFileAsync(
                stream, 
                $"{Guid.NewGuid()}{Path.GetExtension(file.FileName)}",
                file.ContentType);

            return Ok(new { FileUrl = fileUrl, FileName = file.FileName });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "S3 file upload failed");
            return StatusCode(500, "File upload failed");
        }
    }

    [HttpGet("download/{fileName}")]
    public async Task<IActionResult> DownloadFile(string fileName)
    {
        try
        {
            var stream = await _fileStorageService.DownloadFileAsync(fileName);
            if (stream == null)
                return NotFound();

            return File(stream, "application/octet-stream", fileName);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"S3 file download failed: {fileName}");
            return StatusCode(500, "File download failed");
        }
    }

    [HttpGet("presigned-url/{fileName}")]
    public async Task<IActionResult> GetPresignedUrl(string fileName, [FromQuery] int expiresInMinutes = 60)
    {
        try
        {
            var expiration = DateTime.UtcNow.AddMinutes(expiresInMinutes);
            var presignedUrl = await _fileStorageService.GeneratePresignedUrlAsync(fileName, expiration);
            
            return Ok(new { PresignedUrl = presignedUrl, Expires = expiration });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to generate presigned URL for: {fileName}");
            return StatusCode(500, "Failed to generate presigned URL");
        }
    }
}
  

3.3 AWS RDS with SQL Server

3.3.1 Entity Framework Core with AWS RDS

  
    // AWS RDS Configuration
public class AwsRdsDbContext : DbContext
{
    private readonly IConfiguration _configuration;
    private readonly ILogger<AwsRdsDbContext> _logger;

    public AwsRdsDbContext(DbContextOptions<AwsRdsDbContext> options, 
                          IConfiguration configuration, 
                          ILogger<AwsRdsDbContext> logger) 
        : base(options)
    {
        _configuration = configuration;
        _logger = logger;
    }

    public DbSet<Order> Orders { get; set; }
    public DbSet<OrderItem> OrderItems { get; set; }
    public DbSet<Customer> Customers { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            var connectionString = _configuration.GetConnectionString("AwsRds");
            
            optionsBuilder.UseSqlServer(connectionString, options =>
            {
                options.EnableRetryOnFailure(
                    maxRetryCount: 5,
                    maxRetryDelay: TimeSpan.FromSeconds(30),
                    errorNumbersToAdd: null);
                
                options.CommandTimeout(60);  // 60 second command timeout
            });
            
            // Enable sensitive data logging only in development
            if (_configuration.GetValue<bool>("Logging:EnableSensitiveDataLogging"))
            {
                optionsBuilder.EnableSensitiveDataLogging();
            }
        }
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Configure for RDS performance
        modelBuilder.Entity<Order>(entity =>
        {
            entity.HasKey(e => e.Id);
            entity.HasIndex(e => e.CustomerId);
            entity.HasIndex(e => e.OrderDate);
            entity.HasIndex(e => e.Status);
            
            entity.Property(e => e.TotalAmount)
                  .HasColumnType("decimal(18,2)");
            
            // Configure relationships
            entity.HasOne(e => e.Customer)
                  .WithMany(c => c.Orders)
                  .HasForeignKey(e => e.CustomerId)
                  .OnDelete(DeleteBehavior.Restrict);
        });

        modelBuilder.Entity<OrderItem>(entity =>
        {
            entity.HasKey(e => e.Id);
            entity.HasIndex(e => e.OrderId);
            entity.HasIndex(e => e.ProductId);
            
            entity.Property(e => e.UnitPrice)
                  .HasColumnType("decimal(18,2)");
            entity.Property(e => e.TotalPrice)
                  .HasColumnType("decimal(18,2)")
                  .HasComputedColumnSql("[UnitPrice] * [Quantity]");
        });

        // Soft delete configuration
        modelBuilder.Entity<Customer>(entity =>
        {
            entity.HasQueryFilter(e => !e.IsDeleted);
        });
    }

    public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
    {
        // Audit trail
        var entries = ChangeTracker.Entries()
            .Where(e => e.Entity is IAuditable && 
                       (e.State == EntityState.Added || e.State == EntityState.Modified));

        foreach (var entityEntry in entries)
        {
            var auditable = (IAuditable)entityEntry.Entity;
            
            if (entityEntry.State == EntityState.Added)
            {
                auditable.CreatedAt = DateTime.UtcNow;
                auditable.CreatedBy = GetCurrentUserId();
            }
            else
            {
                auditable.UpdatedAt = DateTime.UtcNow;
                auditable.UpdatedBy = GetCurrentUserId();
            }
        }

        try
        {
            return await base.SaveChangesAsync(cancellationToken);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error saving changes to database");
            throw;
        }
    }

    private string GetCurrentUserId()
    {
        // Implement your user ID retrieval logic
        return "system";  // Placeholder
    }
}

// Repository pattern with RDS
public class OrderRepository : IOrderRepository
{
    private readonly AwsRdsDbContext _context;
    private readonly ILogger<OrderRepository> _logger;

    public OrderRepository(AwsRdsDbContext context, ILogger<OrderRepository> logger)
    {
        _context = context;
        _logger = logger;
    }

    public async Task<Order> GetOrderByIdAsync(int orderId)
    {
        try
        {
            return await _context.Orders
                .Include(o => o.Customer)
                .Include(o => o.OrderItems)
                .ThenInclude(oi => oi.Product)
                .FirstOrDefaultAsync(o => o.Id == orderId);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Error retrieving order {orderId}");
            throw;
        }
    }

    public async Task<List<Order>> GetOrdersByCustomerAsync(int customerId, DateTime? startDate = null, DateTime? endDate = null)
    {
        try
        {
            var query = _context.Orders
                .Where(o => o.CustomerId == customerId);

            if (startDate.HasValue)
                query = query.Where(o => o.OrderDate >= startDate.Value);
            
            if (endDate.HasValue)
                query = query.Where(o => o.OrderDate <= endDate.Value);

            return await query
                .OrderByDescending(o => o.OrderDate)
                .ToListAsync();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Error retrieving orders for customer {customerId}");
            throw;
        }
    }

    public async Task<Order> CreateOrderAsync(Order order)
    {
        try
        {
            _context.Orders.Add(order);
            await _context.SaveChangesAsync();
            return order;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error creating order");
            throw;
        }
    }

    public async Task<bool> UpdateOrderStatusAsync(int orderId, OrderStatus status)
    {
        try
        {
            var order = await _context.Orders.FindAsync(orderId);
            if (order == null)
                return false;

            order.Status = status;
            await _context.SaveChangesAsync();
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Error updating order status for {orderId}");
            throw;
        }
    }
}
  

4. Global Scaling Strategies

4.1 Content Delivery Network (CDN) Integration

4.1.1 Azure CDN with ASP.NET Core

  
    // Azure CDN Service
using Azure.ResourceManager.Cdn;
using Azure.ResourceManager.Cdn.Models;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

public class AzureCdnService
{
    private readonly CdnManagementClient _cdnClient;
    private readonly string _resourceGroupName;
    private readonly string _profileName;
    private readonly ILogger<AzureCdnService> _logger;

    public AzureCdnService(IConfiguration configuration, ILogger<AzureCdnService> logger)
    {
        var connectionString = configuration.GetConnectionString("AzureCdn");
        _cdnClient = new CdnManagementClient(new Uri(connectionString), 
                                           new DefaultAzureCredential());
        _resourceGroupName = configuration["Azure:Cdn:ResourceGroup"];
        _profileName = configuration["Azure:Cdn:ProfileName"];
        _logger = logger;
    }

    public async Task PurgeCdnCacheAsync(List<string> contentPaths)
    {
        try
        {
            var purgeParameters = new PurgeParameters(contentPaths);
            await _cdnClient.Endpoints.PurgeContentAsync(
                _resourceGroupName, 
                _profileName, 
                "my-endpoint", 
                purgeParameters);

            _logger.LogInformation($"CDN cache purged for {contentPaths.Count} paths");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to purge CDN cache");
            throw;
        }
    }

    public async Task LoadCdnContentAsync(List<string> contentPaths)
    {
        try
        {
            var loadParameters = new LoadParameters(contentPaths);
            await _cdnClient.Endpoints.LoadContentAsync(
                _resourceGroupName, 
                _profileName, 
                "my-endpoint", 
                loadParameters);

            _logger.LogInformation($"CDN content loaded for {contentPaths.Count} paths");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to load CDN content");
            throw;
        }
    }
}

// CDN Helper for ASP.NET Core
public static class CdnHelper
{
    private static readonly string _cdnUrl;

    static CdnHelper()
    {
        _cdnUrl = "https://my-cdn.azureedge.net";
    }

    public static string GetCdnUrl(string relativePath)
    {
        if (string.IsNullOrEmpty(relativePath))
            return relativePath;

        // Remove leading slash if present
        if (relativePath.StartsWith("/"))
            relativePath = relativePath.Substring(1);

        return $"{_cdnUrl}/{relativePath}";
    }

    public static string GetImageUrl(string imageName, string size = "original")
    {
        return $"{_cdnUrl}/images/{size}/{imageName}";
    }

    public static string GetScriptUrl(string scriptName, bool minified = true)
    {
        var extension = minified ? ".min.js" : ".js";
        return $"{_cdnUrl}/scripts/{scriptName}{extension}";
    }

    public static string GetStyleUrl(string styleName, bool minified = true)
    {
        var extension = minified ? ".min.css" : ".css";
        return $"{_cdnUrl}/styles/{styleName}{extension}";
    }
}

// Tag Helper for CDN URLs
[HtmlTargetElement("cdn-script")]
public class CdnScriptTagHelper : TagHelper
{
    [HtmlAttributeName("src")]
    public string Source { get; set; }

    [HtmlAttributeName("minified")]
    public bool Minified { get; set; } = true;

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        output.TagName = "script";
        output.Attributes.SetAttribute("src", CdnHelper.GetScriptUrl(Source, Minified));
        output.Attributes.SetAttribute("crossorigin", "anonymous");
    }
}

[HtmlTargetElement("cdn-style")]
public class CdnStyleTagHelper : TagHelper
{
    [HtmlAttributeName("href")]
    public string Href { get; set; }

    [HtmlAttributeName("minified")]
    public bool Minified { get; set; } = true;

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        output.TagName = "link";
        output.Attributes.SetAttribute("rel", "stylesheet");
        output.Attributes.SetAttribute("href", CdnHelper.GetStyleUrl(Href, Minified));
        output.Attributes.SetAttribute("crossorigin", "anonymous");
    }
}

// Usage in Razor views
@* 
<cdn-script src="site" minified="true"></cdn-script>
<cdn-style href="bootstrap" minified="true"></cdn-style>
*@
  

4.1.2 AWS CloudFront Integration

  
    // AWS CloudFront Service
using Amazon.CloudFront;
using Amazon.CloudFront.Model;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

public class AwsCloudFrontService
{
    private readonly IAmazonCloudFront _cloudFrontClient;
    private readonly string _distributionId;
    private readonly ILogger<AwsCloudFrontService> _logger;

    public AwsCloudFrontService(IAmazonCloudFront cloudFrontClient, 
                              IConfiguration configuration, 
                              ILogger<AwsCloudFrontService> logger)
    {
        _cloudFrontClient = cloudFrontClient;
        _distributionId = configuration["AWS:CloudFront:DistributionId"];
        _logger = logger;
    }

    public async Task CreateInvalidationAsync(List<string> paths)
    {
        try
        {
            var invalidationBatch = new InvalidationBatch
            {
                CallerReference = DateTime.UtcNow.Ticks.ToString(),
                Paths = new Paths
                {
                    Items = paths,
                    Quantity = paths.Count
                }
            };

            var request = new CreateInvalidationRequest
            {
                DistributionId = _distributionId,
                InvalidationBatch = invalidationBatch
            };

            await _cloudFrontClient.CreateInvalidationAsync(request);
            
            _logger.LogInformation($"CloudFront invalidation created for {paths.Count} paths");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to create CloudFront invalidation");
            throw;
        }
    }

    public string GetSignedUrl(string resourceUrl, DateTime expiryTime)
    {
        var url = CloudFrontSigner.GetCannedSignedURL(
            CloudFrontSigner.Protocol.https,
            "d123.cloudfront.net",
            null, // private key file path would be configured
            resourceUrl,
            "key-pair-id", // from AWS
            expiryTime);

        return url;
    }
}

// CloudFront URL Helper
public static class CloudFrontHelper
{
    private static readonly string _cloudFrontDomain = "d123.cloudfront.net";

    public static string GetResourceUrl(string resourcePath)
    {
        return $"https://{_cloudFrontDomain}/{resourcePath.TrimStart('/')}";
    }

    public static string GetImageUrl(string imageName, string version = null)
    {
        var url = $"images/{imageName}";
        if (!string.IsNullOrEmpty(version))
        {
            url += $"?v={version}";
        }
        return GetResourceUrl(url);
    }

    public static string GetAssetUrl(string assetPath, bool cacheBust = true)
    {
        var url = $"assets/{assetPath}";
        if (cacheBust)
        {
            var version = Guid.NewGuid().ToString("N").Substring(0, 8);
            url += $"?v={version}";
        }
        return GetResourceUrl(url);
    }
}
  

4.2 Global Database Strategies

4.2.1 Multi-Region Database Setup

  
    // Global Database Context
public class GlobalDbContext : DbContext
{
    private readonly IConfiguration _configuration;
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly ILogger<GlobalDbContext> _logger;

    public GlobalDbContext(DbContextOptions<GlobalDbContext> options,
                          IConfiguration configuration,
                          IHttpContextAccessor httpContextAccessor,
                          ILogger<GlobalDbContext> logger)
        : base(options)
    {
        _configuration = configuration;
        _httpContextAccessor = httpContextAccessor;
        _logger = logger;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            var connectionString = GetRegionalConnectionString();
            optionsBuilder.UseSqlServer(connectionString, options =>
            {
                options.EnableRetryOnFailure(
                    maxRetryCount: 3,
                    maxRetryDelay: TimeSpan.FromSeconds(10),
                    errorNumbersToAdd: null);
            });
        }
    }

    private string GetRegionalConnectionString()
    {
        // Determine user's region from request headers or GeoIP
        var userRegion = GetUserRegion();
        
        // Get appropriate connection string for the region
        var regionalConfigKey = $"Database:ConnectionStrings:{userRegion}";
        var connectionString = _configuration[regionalConfigKey];
        
        if (string.IsNullOrEmpty(connectionString))
        {
            // Fallback to primary region
            connectionString = _configuration["Database:ConnectionStrings:Primary"];
            _logger.LogWarning($"Using primary database connection for region: {userRegion}");
        }

        return connectionString;
    }

    private string GetUserRegion()
    {
        var httpContext = _httpContextAccessor.HttpContext;
        if (httpContext?.Request == null)
            return "Primary"; // Default region

        // Check for region header (set by CDN or load balancer)
        var regionHeader = httpContext.Request.Headers["X-User-Region"].FirstOrDefault();
        if (!string.IsNullOrEmpty(regionHeader))
            return regionHeader;

        // Fallback: determine region from IP address (simplified)
        var userIp = httpContext.Connection.RemoteIpAddress?.ToString();
        return DetermineRegionFromIp(userIp);
    }

    private string DetermineRegionFromIp(string ipAddress)
    {
        // Simplified region determination
        // In production, use GeoIP service
        if (string.IsNullOrEmpty(ipAddress))
            return "Primary";

        // Example logic - replace with actual GeoIP service
        return ipAddress.StartsWith("192.168.") ? "Primary" : "Secondary";
    }
}

// Database synchronization service
public class DatabaseSynchronizationService
{
    private readonly IConfiguration _configuration;
    private readonly ILogger<DatabaseSynchronizationService> _logger;

    public DatabaseSynchronizationService(IConfiguration configuration, 
                                        ILogger<DatabaseSynchronizationService> logger)
    {
        _configuration = configuration;
        _logger = logger;
    }

    public async Task SynchronizeDataAsync<T>(string sourceRegion, string targetRegion, 
                                            DateTime? since = null) where T : class
    {
        try
        {
            using var sourceContext = CreateDbContext(sourceRegion);
            using var targetContext = CreateDbContext(targetRegion);

            var query = sourceContext.Set<T>().AsQueryable();
            
            if (since.HasValue)
            {
                // Assuming entities have a LastModified property
                query = query.Where(e => EF.Property<DateTime>(e, "LastModified") > since.Value);
            }

            var entities = await query.ToListAsync();
            
            foreach (var entity in entities)
            {
                var existingEntity = await targetContext.Set<T>().FindAsync(GetKeyValues(entity));
                if (existingEntity == null)
                {
                    targetContext.Set<T>().Add(entity);
                }
                else
                {
                    targetContext.Entry(existingEntity).CurrentValues.SetValues(entity);
                }
            }

            await targetContext.SaveChangesAsync();
            
            _logger.LogInformation($"Synchronized {entities.Count} {typeof(T).Name} entities from {sourceRegion} to {targetRegion}");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to synchronize data from {sourceRegion} to {targetRegion}");
            throw;
        }
    }

    private object[] GetKeyValues<T>(T entity) where T : class
    {
        // Implementation to get primary key values
        // This is a simplified version
        var keyProperties = typeof(T).GetProperties()
            .Where(p => p.Name == "Id" || p.Name.EndsWith("Id"))
            .ToArray();

        return keyProperties.Select(p => p.GetValue(entity)).ToArray();
    }

    private DbContext CreateDbContext(string region)
    {
        var optionsBuilder = new DbContextOptionsBuilder<GlobalDbContext>();
        var connectionString = _configuration[$"Database:ConnectionStrings:{region}"];
        
        optionsBuilder.UseSqlServer(connectionString);
        return new GlobalDbContext(optionsBuilder.Options, _configuration, null, _logger);
    }
}
  

5. Cloud Storage Solutions

5.1 Multi-Cloud Storage Abstraction

  
    // Unified Cloud Storage Interface
public interface ICloudStorageService
{
    Task<string> UploadFileAsync(Stream fileStream, string fileName, string contentType);
    Task<Stream> DownloadFileAsync(string fileName);
    Task<bool> DeleteFileAsync(string fileName);
    Task<bool> FileExistsAsync(string fileName);
    Task<FileMetadata> GetFileMetadataAsync(string fileName);
    Task<List<string>> ListFilesAsync(string prefix = null);
    Task<string> GenerateDownloadUrlAsync(string fileName, TimeSpan expiryDuration);
}

public class FileMetadata
{
    public string FileName { get; set; }
    public long Size { get; set; }
    public string ContentType { get; set; }
    public DateTime LastModified { get; set; }
    public string ETag { get; set; }
}

// Multi-Cloud Storage Service
public class MultiCloudStorageService : ICloudStorageService
{
    private readonly IAzureBlobStorageService _azureStorage;
    private readonly IAwsS3StorageService _awsStorage;
    private readonly IConfiguration _configuration;
    private readonly ILogger<MultiCloudStorageService> _logger;

    public MultiCloudStorageService(IAzureBlobStorageService azureStorage,
                                  IAwsS3StorageService awsStorage,
                                  IConfiguration configuration,
                                  ILogger<MultiCloudStorageService> logger)
    {
        _azureStorage = azureStorage;
        _awsStorage = awsStorage;
        _configuration = configuration;
        _logger = logger;
    }

    public async Task<string> UploadFileAsync(Stream fileStream, string fileName, string contentType)
    {
        var primaryProvider = GetPrimaryStorageProvider();
        
        try
        {
            string fileUrl;
            
            if (primaryProvider == StorageProvider.Azure)
            {
                fileUrl = await _azureStorage.UploadFileAsync(fileStream, fileName, contentType);
                
                // Async replication to secondary provider
                _ = Task.Run(async () =>
                {
                    try
                    {
                        fileStream.Position = 0; // Reset stream position
                        await _awsStorage.UploadFileAsync(fileStream, fileName, contentType);
                        _logger.LogInformation($"File replicated to secondary storage: {fileName}");
                    }
                    catch (Exception ex)
                    {
                        _logger.LogWarning(ex, $"Failed to replicate file to secondary storage: {fileName}");
                    }
                });
            }
            else
            {
                fileUrl = await _awsStorage.UploadFileAsync(fileStream, fileName, contentType);
                
                // Async replication to secondary provider
                _ = Task.Run(async () =>
                {
                    try
                    {
                        fileStream.Position = 0; // Reset stream position
                        await _azureStorage.UploadFileAsync(fileStream, fileName, contentType);
                        _logger.LogInformation($"File replicated to secondary storage: {fileName}");
                    }
                    catch (Exception ex)
                    {
                        _logger.LogWarning(ex, $"Failed to replicate file to secondary storage: {fileName}");
                    }
                });
            }

            return fileUrl;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to upload file: {fileName} to primary storage");
            
            // Fallback to secondary provider
            try
            {
                fileStream.Position = 0;
                var fallbackUrl = await GetSecondaryStorageProvider().UploadFileAsync(fileStream, fileName, contentType);
                _logger.LogWarning($"File uploaded to secondary storage as fallback: {fileName}");
                return fallbackUrl;
            }
            catch (Exception fallbackEx)
            {
                _logger.LogError(fallbackEx, $"Failed to upload file to secondary storage: {fileName}");
                throw new StorageException("All storage providers failed", ex);
            }
        }
    }

    public async Task<Stream> DownloadFileAsync(string fileName)
    {
        // Try primary provider first
        try
        {
            return await GetPrimaryStorageProvider().DownloadFileAsync(fileName);
        }
        catch (Exception primaryEx)
        {
            _logger.LogWarning(primaryEx, $"Failed to download from primary storage: {fileName}");
            
            // Fallback to secondary provider
            try
            {
                var stream = await GetSecondaryStorageProvider().DownloadFileAsync(fileName);
                _logger.LogInformation($"File downloaded from secondary storage: {fileName}");
                return stream;
            }
            catch (Exception secondaryEx)
            {
                _logger.LogError(secondaryEx, $"Failed to download from secondary storage: {fileName}");
                throw new StorageException("All storage providers failed", secondaryEx);
            }
        }
    }

    public async Task<bool> DeleteFileAsync(string fileName)
    {
        var tasks = new List<Task<bool>>
        {
            _azureStorage.DeleteFileAsync(fileName),
            _awsStorage.DeleteFileAsync(fileName)
        };

        var results = await Task.WhenAll(tasks);
        return results.All(r => r);
    }

    public async Task<bool> FileExistsAsync(string fileName)
    {
        // Check primary provider first
        var exists = await GetPrimaryStorageProvider().FileExistsAsync(fileName);
        if (exists)
            return true;

        // Check secondary provider
        return await GetSecondaryStorageProvider().FileExistsAsync(fileName);
    }

    public async Task<FileMetadata> GetFileMetadataAsync(string fileName)
    {
        try
        {
            return await GetPrimaryStorageProvider().GetFileMetadataAsync(fileName);
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, $"Failed to get metadata from primary storage: {fileName}");
            return await GetSecondaryStorageProvider().GetFileMetadataAsync(fileName);
        }
    }

    public async Task<List<string>> ListFilesAsync(string prefix = null)
    {
        // Merge files from both providers, remove duplicates
        var azureFiles = await _azureStorage.ListFilesAsync(prefix);
        var awsFiles = await _awsStorage.ListFilesAsync(prefix);

        return azureFiles.Union(awsFiles).Distinct().ToList();
    }

    public async Task<string> GenerateDownloadUrlAsync(string fileName, TimeSpan expiryDuration)
    {
        try
        {
            return await GetPrimaryStorageProvider().GenerateDownloadUrlAsync(fileName, expiryDuration);
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, $"Failed to generate URL from primary storage: {fileName}");
            return await GetSecondaryStorageProvider().GenerateDownloadUrlAsync(fileName, expiryDuration);
        }
    }

    private ICloudStorageService GetPrimaryStorageProvider()
    {
        var primaryProvider = _configuration["Storage:PrimaryProvider"] ?? "Azure";
        return primaryProvider.Equals("Azure", StringComparison.OrdinalIgnoreCase) 
            ? _azureStorage 
            : _awsStorage;
    }

    private ICloudStorageService GetSecondaryStorageProvider()
    {
        var primaryProvider = _configuration["Storage:PrimaryProvider"] ?? "Azure";
        return primaryProvider.Equals("Azure", StringComparison.OrdinalIgnoreCase) 
            ? _awsStorage 
            : _azureStorage;
    }
}

public enum StorageProvider
{
    Azure,
    AWS
}

public class StorageException : Exception
{
    public StorageException(string message, Exception innerException) 
        : base(message, innerException)
    {
    }
}
  

6. Microservices in Cloud

6.1 Cloud-Native Microservices Architecture

6.1.1 API Gateway Pattern

  
    // Ocelot API Gateway Configuration
public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true);
                config.AddEnvironmentVariables();
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            })
            .ConfigureLogging((context, logging) =>
            {
                logging.AddConsole();
                logging.AddDebug();
                logging.AddApplicationInsights();
            });
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddOcelot()
            .AddConsul()
            .AddConfigStoredInConsul();

        // Add authentication and authorization
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.Authority = "https://login.microsoftonline.com/{tenantId}";
                options.Audience = "api://{api-client-id}";
            });

        services.AddAuthorization();
        
        // Add health checks
        services.AddHealthChecks();
        
        // Add distributed caching for rate limiting
        services.AddDistributedRedisCache(options =>
        {
            options.Configuration = Configuration.GetConnectionString("Redis");
            options.InstanceName = "ApiGateway_";
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();
        
        // Health check endpoint
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapHealthChecks("/health");
        });

        app.UseOcelot().Wait();
    }
}

// ocelot.json configuration
{
  "Routes": [
    {
      "DownstreamPathTemplate": "/api/products",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "products-service",
          "Port": 443
        }
      ],
      "UpstreamPathTemplate": "/products",
      "UpstreamHttpMethod": [ "GET" ],
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "Bearer"
      },
      "RateLimitOptions": {
        "ClientWhitelist": [],
        "EnableRateLimiting": true,
        "Period": "1s",
        "PeriodTimespan": 1,
        "Limit": 100
      }
    },
    {
      "DownstreamPathTemplate": "/api/orders",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "orders-service",
          "Port": 443
        }
      ],
      "UpstreamPathTemplate": "/orders",
      "UpstreamHttpMethod": [ "GET", "POST", "PUT" ],
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "Bearer"
      }
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "https://api.mycompany.com",
    "ServiceDiscoveryProvider": {
      "Host": "consul",
      "Port": 8500,
      "Type": "Consul"
    }
  }
}
  

6.1.2 Microservice Communication

  
    // Resilient HTTP Client Factory
public static class HttpClientFactoryExtensions
{
    public static void AddResilientHttpClient<TClient, TImplementation>(
        this IServiceCollection services, 
        string clientName,
        string baseAddress)
        where TClient : class
        where TImplementation : class, TClient
    {
        services.AddHttpClient<TClient, TImplementation>(clientName, client =>
        {
            client.BaseAddress = new Uri(baseAddress);
            client.DefaultRequestHeaders.Add("User-Agent", "MyApp/1.0");
            client.Timeout = TimeSpan.FromSeconds(30);
        })
        .AddPolicyHandler(GetRetryPolicy())
        .AddPolicyHandler(GetCircuitBreakerPolicy())
        .AddPolicyHandler(GetTimeoutPolicy())
        .AddHttpMessageHandler<LoggingHandler>();
    }

    private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
    {
        return HttpPolicyExtensions
            .HandleTransientHttpError()
            .OrResult(msg => !msg.IsSuccessStatusCode)
            .WaitAndRetryAsync(
                retryCount: 3,
                sleepDurationProvider: retryAttempt => 
                    TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
                onRetry: (outcome, timespan, retryCount, context) =>
                {
                    var logger = context.GetLogger();
                    logger?.LogWarning($"Retry {retryCount} after {timespan.TotalSeconds}s for {context.PolicyKey}");
                });
    }

    private static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy()
    {
        return HttpPolicyExtensions
            .HandleTransientHttpError()
            .CircuitBreakerAsync(
                handledEventsAllowedBeforeBreaking: 3,
                durationOfBreak: TimeSpan.FromSeconds(30),
                onBreak: (outcome, breakDelay, context) =>
                {
                    var logger = context.GetLogger();
                    logger?.LogWarning($"Circuit breaker opened for {breakDelay.TotalSeconds}s");
                },
                onReset: (context) =>
                {
                    var logger = context.GetLogger();
                    logger?.LogInformation("Circuit breaker reset");
                });
    }

    private static IAsyncPolicy<HttpResponseMessage> GetTimeoutPolicy()
    {
        return Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(15));
    }
}

// Logging Handler for HTTP requests
public class LoggingHandler : DelegatingHandler
{
    private readonly ILogger<LoggingHandler> _logger;

    public LoggingHandler(ILogger<LoggingHandler> logger)
    {
        _logger = logger;
    }

    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, 
        CancellationToken cancellationToken)
    {
        var stopwatch = Stopwatch.StartNew();
        
        try
        {
            _logger.LogInformation($"Sending HTTP request: {request.Method} {request.RequestUri}");
            
            var response = await base.SendAsync(request, cancellationToken);
            
            stopwatch.Stop();
            
            _logger.LogInformation($"Received HTTP response: {(int)response.StatusCode} in {stopwatch.ElapsedMilliseconds}ms");
            
            return response;
        }
        catch (Exception ex)
        {
            stopwatch.Stop();
            _logger.LogError(ex, $"HTTP request failed after {stopwatch.ElapsedMilliseconds}ms");
            throw;
        }
    }
}

// Products Service Client
public interface IProductsServiceClient
{
    Task<List<Product>> GetProductsAsync();
    Task<Product> GetProductAsync(int id);
    Task<Product> CreateProductAsync(Product product);
    Task<bool> UpdateProductAsync(Product product);
    Task<bool> DeleteProductAsync(int id);
}

public class ProductsServiceClient : IProductsServiceClient
{
    private readonly HttpClient _httpClient;
    private readonly ILogger<ProductsServiceClient> _logger;

    public ProductsServiceClient(HttpClient httpClient, ILogger<ProductsServiceClient> logger)
    {
        _httpClient = httpClient;
        _logger = logger;
    }

    public async Task<List<Product>> GetProductsAsync()
    {
        try
        {
            var response = await _httpClient.GetAsync("/api/products");
            response.EnsureSuccessStatusCode();
            
            var content = await response.Content.ReadAsStringAsync();
            return JsonSerializer.Deserialize<List<Product>>(content, new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to get products");
            throw;
        }
    }

    public async Task<Product> GetProductAsync(int id)
    {
        try
        {
            var response = await _httpClient.GetAsync($"/api/products/{id}");
            
            if (response.StatusCode == HttpStatusCode.NotFound)
                return null;
                
            response.EnsureSuccessStatusCode();
            
            var content = await response.Content.ReadAsStringAsync();
            return JsonSerializer.Deserialize<Product>(content, new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to get product {id}");
            throw;
        }
    }

    public async Task<Product> CreateProductAsync(Product product)
    {
        try
        {
            var json = JsonSerializer.Serialize(product);
            var content = new StringContent(json, Encoding.UTF8, "application/json");
            
            var response = await _httpClient.PostAsync("/api/products", content);
            response.EnsureSuccessStatusCode();
            
            var responseContent = await response.Content.ReadAsStringAsync();
            return JsonSerializer.Deserialize<Product>(responseContent, new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to create product");
            throw;
        }
    }

    public async Task<bool> UpdateProductAsync(Product product)
    {
        try
        {
            var json = JsonSerializer.Serialize(product);
            var content = new StringContent(json, Encoding.UTF8, "application/json");
            
            var response = await _httpClient.PutAsync($"/api/products/{product.Id}", content);
            return response.IsSuccessStatusCode;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to update product {product.Id}");
            throw;
        }
    }

    public async Task<bool> DeleteProductAsync(int id)
    {
        try
        {
            var response = await _httpClient.DeleteAsync($"/api/products/{id}");
            return response.IsSuccessStatusCode;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to delete product {id}");
            throw;
        }
    }
}

// Service registration
public void ConfigureServices(IServiceCollection services)
{
    services.AddResilientHttpClient<IProductsServiceClient, ProductsServiceClient>(
        "ProductsService", 
        "https://products-service.mycompany.com");
    
    services.AddResilientHttpClient<IOrdersServiceClient, OrdersServiceClient>(
        "OrdersService", 
        "https://orders-service.mycompany.com");
        
    services.AddTransient<LoggingHandler>();
}
  

7. Production Deployment Patterns

7.1 Docker and Kubernetes Deployment

7.1.1 Dockerfile for ASP.NET Core

  
    # Multi-stage build for optimized production image
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

# Build stage
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src

# Copy project files
COPY ["MyApp/MyApp.csproj", "MyApp/"]
COPY ["MyApp.Core/MyApp.Core.csproj", "MyApp.Core/"]
COPY ["MyApp.Infrastructure/MyApp.Infrastructure.csproj", "MyApp.Infrastructure/"]

# Restore dependencies
RUN dotnet restore "MyApp/MyApp.csproj"
COPY . .

# Build application
WORKDIR "/src/MyApp"
RUN dotnet build "MyApp.csproj" -c Release -o /app/build

# Publish stage
FROM build AS publish
RUN dotnet publish "MyApp.csproj" -c Release -o /app/publish /p:UseAppHost=false

# Final stage
FROM base AS final
WORKDIR /app

# Install necessary tools
RUN apt-get update && apt-get install -y \
    curl \
    && rm -rf /var/lib/apt/lists/*

# Create non-root user for security
RUN groupadd -r appuser && useradd -r -g appuser appuser
RUN chown -R appuser:appuser /app
USER appuser

COPY --from=publish /app/publish .

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD curl -f http://localhost/health || exit 1

ENTRYPOINT ["dotnet", "MyApp.dll"]
  

7.1.2 Kubernetes Deployment Configuration

deployment.yaml

  
    apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  labels:
    app: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "80"
        prometheus.io/path: "/metrics"
    spec:
      containers:
      - name: myapp
        image: myregistry.azurecr.io/myapp:latest
        ports:
        - containerPort: 80
        - containerPort: 443
        env:
        - name: ASPNETCORE_ENVIRONMENT
          value: "Production"
        - name: ConnectionStrings__DefaultConnection
          valueFrom:
            secretKeyRef:
              name: myapp-secrets
              key: database-connection-string
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 80
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /health/ready
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 3
        startupProbe:
          httpGet:
            path: /health/startup
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 10
---
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
    app: myapp
  ports:
  - name: http
    port: 80
    targetPort: 80
  - name: https
    port: 443
    targetPort: 443
  type: LoadBalancer
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp-deployment
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  

7.1.3 Kubernetes Ingress Configuration

ingress.yaml

  
    apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
  - hosts:
    - myapp.example.com
    secretName: myapp-tls-secret
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: myapp-service
            port:
              number: 80
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: myapp-service
            port:
              number: 80
  

7.2 CI/CD Pipeline Configuration

7.2.1 GitHub Actions for Azure

.github/workflows/azure-deploy.yml

  
    name: Build and Deploy to Azure

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

env:
  AZURE_WEBAPP_NAME: my-aspnet-app
  AZURE_WEBAPP_PACKAGE_PATH: './publish'
  DOTNET_VERSION: '8.0.x'

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup .NET Core
      uses: actions/setup-dotnet@v3
      with:
        dotnet-version: ${{ env.DOTNET_VERSION }}
        
    - name: Restore dependencies
      run: dotnet restore
      
    - name: Build with dotnet
      run: dotnet build --configuration Release --no-restore
      
    - name: Test with dotnet
      run: dotnet test --verbosity normal --logger trx
      
    - name: Publish with dotnet
      run: dotnet publish -c Release -o ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}
      
    - name: Upload artifact for deployment job
      uses: actions/upload-artifact@v3
      with:
        name: .net-app
        path: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}

  deploy:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: 'Production'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}

    steps:
    - name: Download artifact from build job
      uses: actions/download-artifact@v3
      with:
        name: .net-app
        
    - name: Deploy to Azure Web App
      id: deploy-to-webapp
      uses: azure/webapps-deploy@v2
      with:
        app-name: ${{ env.AZURE_WEBAPP_NAME }}
        publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
        package: .
        
    - name: Run smoke tests
      run: |
        echo "Running smoke tests against ${{ steps.deploy-to-webapp.outputs.webapp-url }}"
        curl -f ${{ steps.deploy-to-webapp.outputs.webapp-url }}/health || exit 1
  

7.2.2 AWS CodePipeline Configuration

buildspec.yml

  
    version: 0.2

phases:
  install:
    runtime-versions:
      dotnet: 8.0
    commands:
      - echo Installing dependencies...
      
  pre_build:
    commands:
      - echo Restoring NuGet packages...
      - dotnet restore
      - echo Running tests...
      - dotnet test --logger trx
      
  build:
    commands:
      - echo Building application...
      - dotnet build --configuration Release
      - echo Publishing application...
      - dotnet publish -c Release -o ./publish
      
  post_build:
    commands:
      - echo Build completed on `date`
      
artifacts:
  files:
    - '**/*'
  base-directory: 'publish'
  discard-paths: no

cache:
  paths:
    - '**/*'
  

8. Real-World Case Study

8.1 E-Commerce Platform Global Scaling

8.1.1 Architecture Overview

Scenario : Global E-Commerce Platform handling 10,000+ transactions per minute during peak seasons.

  
    // Global E-Commerce Architecture Implementation
public class GlobalECommerceService
{
    private readonly IProductService _productService;
    private readonly IOrderService _orderService;
    private readonly IInventoryService _inventoryService;
    private readonly IPaymentService _paymentService;
    private readonly IShippingService _shippingService;
    private readonly ILogger<GlobalECommerceService> _logger;
    private readonly ICacheService _cacheService;
    private readonly IEventBus _eventBus;

    public GlobalECommerceService(
        IProductService productService,
        IOrderService orderService,
        IInventoryService inventoryService,
        IPaymentService paymentService,
        IShippingService shippingService,
        ILogger<GlobalECommerceService> logger,
        ICacheService cacheService,
        IEventBus eventBus)
    {
        _productService = productService;
        _orderService = orderService;
        _inventoryService = inventoryService;
        _paymentService = paymentService;
        _shippingService = shippingService;
        _logger = logger;
        _cacheService = cacheService;
        _eventBus = eventBus;
    }

    public async Task<OrderResult> PlaceOrderAsync(OrderRequest request)
    {
        var stopwatch = Stopwatch.StartNew();
        
        try
        {
            // Step 1: Validate request
            await ValidateOrderRequestAsync(request);

            // Step 2: Check product availability with cache
            var product = await GetProductWithCacheAsync(request.ProductId);
            if (product == null)
                throw new ProductNotFoundException(request.ProductId);

            // Step 3: Reserve inventory
            var inventoryResult = await _inventoryService.ReserveInventoryAsync(
                request.ProductId, request.Quantity, request.Region);
                
            if (!inventoryResult.Success)
                throw new InventoryUnavailableException(request.ProductId);

            // Step 4: Process payment
            var paymentResult = await _paymentService.ProcessPaymentAsync(
                request.PaymentMethod, request.TotalAmount, request.Currency);
                
            if (!paymentResult.Success)
                throw new PaymentFailedException(paymentResult.ErrorMessage);

            // Step 5: Create order
            var order = await _orderService.CreateOrderAsync(request, inventoryResult.ReservationId);

            // Step 6: Publish order created event
            await _eventBus.PublishAsync(new OrderCreatedEvent
            {
                OrderId = order.Id,
                CustomerId = request.CustomerId,
                TotalAmount = request.TotalAmount,
                Currency = request.Currency,
                Region = request.Region,
                Timestamp = DateTime.UtcNow
            });

            // Step 7: Update cache and return result
            await UpdateProductCacheAsync(product);
            
            stopwatch.Stop();
            _logger.LogInformation($"Order {order.Id} placed successfully in {stopwatch.ElapsedMilliseconds}ms");

            return new OrderResult
            {
                Success = true,
                OrderId = order.Id,
                EstimatedDelivery = await _shippingService.GetEstimatedDeliveryAsync(
                    request.Region, order.Id)
            };
        }
        catch (Exception ex)
        {
            stopwatch.Stop();
            _logger.LogError(ex, $"Order placement failed after {stopwatch.ElapsedMilliseconds}ms");
            
            // Compensating actions for failed order
            await CompensateFailedOrderAsync(request);
            throw;
        }
    }

    private async Task<Product> GetProductWithCacheAsync(int productId)
    {
        var cacheKey = $"product:{productId}";
        
        // Try to get from cache first
        var cachedProduct = await _cacheService.GetAsync<Product>(cacheKey);
        if (cachedProduct != null)
            return cachedProduct;

        // If not in cache, get from database
        var product = await _productService.GetProductAsync(productId);
        if (product != null)
        {
            // Cache for 5 minutes with sliding expiration
            await _cacheService.SetAsync(cacheKey, product, TimeSpan.FromMinutes(5));
        }

        return product;
    }

    private async Task UpdateProductCacheAsync(Product product)
    {
        var cacheKey = $"product:{product.Id}";
        await _cacheService.SetAsync(cacheKey, product, TimeSpan.FromMinutes(5));
    }

    private async Task CompensateFailedOrderAsync(OrderRequest request)
    {
        // Implement compensating transactions for failed orders
        try
        {
            // Release reserved inventory
            await _inventoryService.ReleaseReservationAsync(request.ProductId, request.Quantity);
            
            // Refund payment if already processed
            await _paymentService.RefundPaymentAsync(request.PaymentMethod.TransactionId);
            
            _logger.LogInformation($"Compensating actions completed for failed order");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to execute compensating actions");
            // Alert monitoring system about failed compensation
            await _eventBus.PublishAsync(new CompensationFailedEvent
            {
                OrderRequest = request,
                Timestamp = DateTime.UtcNow
            });
        }
    }
}

// Event-driven architecture for order processing
public class OrderCreatedEventHandler : IEventHandler<OrderCreatedEvent>
{
    private readonly IShippingService _shippingService;
    private readonly IEmailService _emailService;
    private readonly IAnalyticsService _analyticsService;
    private readonly ILogger<OrderCreatedEventHandler> _logger;

    public OrderCreatedEventHandler(
        IShippingService shippingService,
        IEmailService emailService,
        IAnalyticsService analyticsService,
        ILogger<OrderCreatedEventHandler> logger)
    {
        _shippingService = shippingService;
        _emailService = emailService;
        _analyticsService = analyticsService;
        _logger = logger;
    }

    public async Task HandleAsync(OrderCreatedEvent @event)
    {
        try
        {
            // Process shipping asynchronously
            var shippingTask = _shippingService.ProcessShippingAsync(@event.OrderId, @event.Region);
            
            // Send confirmation email
            var emailTask = _emailService.SendOrderConfirmationAsync(@event.OrderId, @event.CustomerId);
            
            // Update analytics
            var analyticsTask = _analyticsService.TrackOrderAsync(@event);

            // Wait for all tasks to complete
            await Task.WhenAll(shippingTask, emailTask, analyticsTask);
            
            _logger.LogInformation($"Order {@event.OrderId} processed successfully");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to process order {@event.OrderId}");
            throw;
        }
    }
}
  

9. Best Practices & Optimization

9.1 Performance Optimization

9.1.1 Caching Strategies

  
    // Distributed Cache Service
public interface IDistributedCacheService
{
    Task<T> GetAsync<T>(string key);
    Task SetAsync<T>(string key, T value, TimeSpan? expiration = null);
    Task<bool> RemoveAsync(string key);
    Task<bool> ExistsAsync(string key);
    Task<TimeSpan?> GetTimeToLiveAsync(string key);
    Task<bool> SetExpirationAsync(string key, TimeSpan expiration);
}

public class RedisCacheService : IDistributedCacheService
{
    private readonly IConnectionMultiplexer _redis;
    private readonly IDatabase _database;
    private readonly ILogger<RedisCacheService> _logger;
    private readonly JsonSerializerOptions _jsonOptions;

    public RedisCacheService(IConnectionMultiplexer redis, ILogger<RedisCacheService> logger)
    {
        _redis = redis;
        _database = redis.GetDatabase();
        _logger = logger;
        
        _jsonOptions = new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            WriteIndented = false
        };
    }

    public async Task<T> GetAsync<T>(string key)
    {
        try
        {
            var cachedValue = await _database.StringGetAsync(key);
            if (cachedValue.IsNull)
                return default;

            return JsonSerializer.Deserialize<T>(cachedValue, _jsonOptions);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to get cache value for key: {key}");
            return default;
        }
    }

    public async Task SetAsync<T>(string key, T value, TimeSpan? expiration = null)
    {
        try
        {
            var serializedValue = JsonSerializer.Serialize(value, _jsonOptions);
            await _database.StringSetAsync(key, serializedValue, expiration);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to set cache value for key: {key}");
        }
    }

    public async Task<bool> RemoveAsync(string key)
    {
        try
        {
            return await _database.KeyDeleteAsync(key);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to remove cache key: {key}");
            return false;
        }
    }

    public async Task<bool> ExistsAsync(string key)
    {
        try
        {
            return await _database.KeyExistsAsync(key);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to check cache key existence: {key}");
            return false;
        }
    }

    public async Task<TimeSpan?> GetTimeToLiveAsync(string key)
    {
        try
        {
            return await _database.KeyTimeToLiveAsync(key);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to get TTL for key: {key}");
            return null;
        }
    }

    public async Task<bool> SetExpirationAsync(string key, TimeSpan expiration)
    {
        try
        {
            return await _database.KeyExpireAsync(key, expiration);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to set expiration for key: {key}");
            return false;
        }
    }
}

// Cache-Aside Pattern Implementation
public class CachedProductService : IProductService
{
    private readonly IProductService _decoratedService;
    private readonly IDistributedCacheService _cacheService;
    private readonly ILogger<CachedProductService> _logger;

    public CachedProductService(
        IProductService decoratedService,
        IDistributedCacheService cacheService,
        ILogger<CachedProductService> logger)
    {
        _decoratedService = decoratedService;
        _cacheService = cacheService;
        _logger = logger;
    }

    public async Task<Product> GetProductAsync(int productId)
    {
        var cacheKey = $"product:{productId}";
        
        try
        {
            // Try to get from cache first
            var cachedProduct = await _cacheService.GetAsync<Product>(cacheKey);
            if (cachedProduct != null)
            {
                _logger.LogDebug($"Cache hit for product {productId}");
                return cachedProduct;
            }

            // Cache miss - get from underlying service
            _logger.LogDebug($"Cache miss for product {productId}");
            var product = await _decoratedService.GetProductAsync(productId);
            
            if (product != null)
            {
                // Cache the product with appropriate expiration
                var expiration = GetCacheExpiration(product);
                await _cacheService.SetAsync(cacheKey, product, expiration);
            }

            return product;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Error in cached product service for product {productId}");
            
            // Fallback to underlying service if cache fails
            return await _decoratedService.GetProductAsync(productId);
        }
    }

    public async Task<List<Product>> GetProductsByCategoryAsync(int categoryId)
    {
        var cacheKey = $"products:category:{categoryId}";
        
        try
        {
            var cachedProducts = await _cacheService.GetAsync<List<Product>>(cacheKey);
            if (cachedProducts != null)
            {
                _logger.LogDebug($"Cache hit for category {categoryId}");
                return cachedProducts;
            }

            _logger.LogDebug($"Cache miss for category {categoryId}");
            var products = await _decoratedService.GetProductsByCategoryAsync(categoryId);
            
            if (products?.Any() == true)
            {
                await _cacheService.SetAsync(cacheKey, products, TimeSpan.FromMinutes(10));
            }

            return products;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Error getting cached products for category {categoryId}");
            return await _decoratedService.GetProductsByCategoryAsync(categoryId);
        }
    }

    public async Task<Product> CreateProductAsync(Product product)
    {
        var result = await _decoratedService.CreateProductAsync(product);
        
        // Invalidate relevant cache entries
        await InvalidateProductCacheAsync(product.Id, product.CategoryId);
        
        return result;
    }

    public async Task<bool> UpdateProductAsync(Product product)
    {
        var result = await _decoratedService.UpdateProductAsync(product);
        
        if (result)
        {
            // Invalidate relevant cache entries
            await InvalidateProductCacheAsync(product.Id, product.CategoryId);
        }
        
        return result;
    }

    public async Task<bool> DeleteProductAsync(int productId)
    {
        // Get product before deletion to know category for cache invalidation
        var product = await _decoratedService.GetProductAsync(productId);
        var result = await _decoratedService.DeleteProductAsync(productId);
        
        if (result && product != null)
        {
            await InvalidateProductCacheAsync(productId, product.CategoryId);
        }
        
        return result;
    }

    private async Task InvalidateProductCacheAsync(int productId, int categoryId)
    {
        var tasks = new List<Task>
        {
            _cacheService.RemoveAsync($"product:{productId}"),
            _cacheService.RemoveAsync($"products:category:{categoryId}"),
            _cacheService.RemoveAsync("products:featured"),
            _cacheService.RemoveAsync("products:popular")
        };

        await Task.WhenAll(tasks);
        _logger.LogDebug($"Invalidated cache for product {productId}");
    }

    private TimeSpan GetCacheExpiration(Product product)
    {
        // Dynamic cache expiration based on product properties
        if (product.IsFeatured)
            return TimeSpan.FromMinutes(5); // Shorter cache for featured products
        
        if (product.LastModified > DateTime.UtcNow.AddDays(-7))
            return TimeSpan.FromMinutes(15); // Recently modified products
        
        return TimeSpan.FromMinutes(30); // Standard cache duration
    }
}
  

9.2 Security Best Practices

9.2.1 Cloud Security Implementation

  
    // Security Headers Middleware
public class SecurityHeadersMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<SecurityHeadersMiddleware> _logger;

    public SecurityHeadersMiddleware(RequestDelegate next, ILogger<SecurityHeadersMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // Add security headers to response
        context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
        context.Response.Headers.Add("X-Frame-Options", "DENY");
        context.Response.Headers.Add("X-XSS-Protection", "1; mode=block");
        context.Response.Headers.Add("Referrer-Policy", "strict-origin-when-cross-origin");
        
        // Content Security Policy
        context.Response.Headers.Add("Content-Security-Policy", 
            "default-src 'self'; " +
            "script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; " +
            "style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; " +
            "img-src 'self' data: https:; " +
            "connect-src 'self' https://api.myapp.com;");
        
        // Feature Policy
        context.Response.Headers.Add("Feature-Policy",
            "camera 'none'; " +
            "microphone 'none'; " +
            "geolocation 'none'");

        await _next(context);
    }
}

// Azure Key Vault Integration for Secrets Management
public class KeyVaultService : ISecretsService
{
    private readonly SecretClient _secretClient;
    private readonly ILogger<KeyVaultService> _logger;
    private readonly Dictionary<string, string> _cache;
    private readonly TimeSpan _cacheDuration;

    public KeyVaultService(IConfiguration configuration, ILogger<KeyVaultService> logger)
    {
        var keyVaultUrl = configuration["KeyVault:Endpoint"];
        _secretClient = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());
        _logger = logger;
        _cache = new Dictionary<string, string>();
        _cacheDuration = TimeSpan.FromMinutes(30);
    }

    public async Task<string> GetSecretAsync(string secretName)
    {
        // Check cache first
        if (_cache.TryGetValue(secretName, out var cachedValue) && 
            !string.IsNullOrEmpty(cachedValue))
        {
            return cachedValue;
        }

        try
        {
            var secret = await _secretClient.GetSecretAsync(secretName);
            var secretValue = secret.Value.Value;
            
            // Cache the secret
            _cache[secretName] = secretValue;
            
            // Set up cache expiration
            _ = Task.Delay(_cacheDuration).ContinueWith(_ => 
            {
                _cache.Remove(secretName);
                _logger.LogDebug($"Cache expired for secret: {secretName}");
            });

            return secretValue;
        }
        catch (RequestFailedException ex) when (ex.Status == 404)
        {
            _logger.LogWarning($"Secret not found: {secretName}");
            return null;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to retrieve secret: {secretName}");
            throw;
        }
    }

    public async Task SetSecretAsync(string secretName, string secretValue)
    {
        try
        {
            await _secretClient.SetSecretAsync(secretName, secretValue);
            
            // Update cache
            _cache[secretName] = secretValue;
            
            _logger.LogInformation($"Secret updated: {secretName}");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Failed to set secret: {secretName}");
            throw;
        }
    }
}

// JWT Token Validation Service
public class JwtTokenService : ITokenService
{
    private readonly IConfiguration _configuration;
    private readonly ILogger<JwtTokenService> _logger;
    private readonly TokenValidationParameters _validationParameters;

    public JwtTokenService(IConfiguration configuration, ILogger<JwtTokenService> logger)
    {
        _configuration = configuration;
        _logger = logger;
        
        _validationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = configuration["Jwt:Issuer"],
            ValidAudience = configuration["Jwt:Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(configuration["Jwt:SecretKey"])),
            ClockSkew = TimeSpan.Zero // No clock skew for production
        };
    }

    public async Task<string> GenerateTokenAsync(User user)
    {
        try
        {
            var claims = new[]
            {
                new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()),
                new Claim(JwtRegisteredClaimNames.Email, user.Email),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                new Claim(ClaimTypes.Role, user.Role),
                new Claim("region", user.Region)
            };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecretKey"]));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            var token = new JwtSecurityToken(
                issuer: _configuration["Jwt:Issuer"],
                audience: _configuration["Jwt:Audience"],
                claims: claims,
                expires: DateTime.UtcNow.AddMinutes(Convert.ToDouble(_configuration["Jwt:ExpiryMinutes"])),
                signingCredentials: creds);

            return new JwtSecurityTokenHandler().WriteToken(token);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to generate JWT token");
            throw;
        }
    }

    public async Task<ClaimsPrincipal> ValidateTokenAsync(string token)
    {
        try
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            var principal = tokenHandler.ValidateToken(token, _validationParameters, out var validatedToken);
            
            return principal;
        }
        catch (SecurityTokenExpiredException ex)
        {
            _logger.LogWarning($"Token expired: {ex.Message}");
            throw;
        }
        catch (SecurityTokenInvalidSignatureException ex)
        {
            _logger.LogWarning($"Invalid token signature: {ex.Message}");
            throw;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Token validation failed");
            throw;
        }
    }

    public async Task<bool> IsTokenValidAsync(string token)
    {
        try
        {
            await ValidateTokenAsync(token);
            return true;
        }
        catch
        {
            return false;
        }
    }
}
  

This comprehensive guide covers the essential aspects of cloud domination with ASP.NET Core, providing you with the knowledge and tools to build scalable, resilient, and high-performance applications in the cloud. The examples and patterns shown here are production-ready and can be adapted to your specific use cases.

Remember that cloud success requires continuous learning and adaptation. Stay updated with the latest cloud services, monitor your applications proactively, and always prioritize security and performance in your implementations.