OElite.Common 5.0.9-develop.511

OElite.Common

Core shared components and foundational infrastructure for the OElite enterprise eCommerce platform.

NuGet Version .NET

Overview

OElite.Common provides essential shared components, infrastructure patterns, and core functionality that forms the foundation of all OElite applications. This package includes configuration management, security abstractions, model transformation capabilities, data synchronization utilities, and business domain models.

Features

🔧 Infrastructure Components

  • Configuration Management: Standardized app configuration patterns with JSON parsing
  • Multi-tenant Security: Request context and authentication abstractions
  • Path Resolution: Flexible path management with type-safe directory structures
  • Shared Resource Management: Optimized connection pooling for Redis and other resources

🔄 Model Transformation System

  • Dynamic Model Transformation: Flexible object transformation with context awareness
  • Priority-based Processing: Configurable transformation pipelines
  • Type-safe Operations: Generic and non-generic interfaces for maximum flexibility

📊 Data Synchronization

  • DataSync Job Management: Standardized job definitions for background data sync
  • RabbitMQ Integration: Message-based synchronization with retry capabilities
  • Denormalized Field Support: Automated field refresh and cascade update support

🏢 Business Domain Models

  • Product Feed Integration: Bing Shopping and other external feed models
  • Security Abstractions: Claims, tokens, and request context management
  • Exception Handling: Business-specific exception patterns

Quick Start

1. Installation

dotnet add package OElite.Common

2. Basic Configuration Setup

using OElite.Common.Infrastructure;
using OElite.Common.Helpers;

// Create your app configuration class
public class MyAppConfig : BaseAppConfig
{
    public override string? DbCentreFullClassName =>
        "MyApp.Data.MyDbCentre, MyApp.Data";

    public MyAppConfig(string jsonConfig, ILogger? logger = null)
        : base(OeAppType.GeneralWebApp, jsonConfig, logger)
    {
    }
}

// Initialize with JSON configuration
var jsonConfig = """
{
  "oelite": {
    "data": {
      "mongodb": {
        "app": "mongodb://localhost:27017/myapp"
      },
      "redis": {
        "app": "localhost:6379"
      }
    },
    "storage": {
      "s3": {
        "app": "https://s3.amazonaws.com/bucket-name"
      }
    }
  }
}
""";

var appConfig = new MyAppConfig(jsonConfig, logger);

// Access configured resources
var mongoConnection = appConfig.DataConfig?.MongoDbConnectionString;
var redisCache = appConfig.RedisCache; // Shared Rest instance
var s3Storage = appConfig.Storage;      // S3 Rest instance

3. Request Context for Multi-tenant Operations

using OElite.Common.Security;

// Create request context for tenant operations
var requestContext = new RequestContext
{
    MerchantId = DbObjectId.Parse("507f1f77bcf86cd799439011"),
    UserId = DbObjectId.Parse("507f1f77bcf86cd799439012"),
    ClientIp = IPAddress.Parse("192.168.1.1"),
    CorrelationId = "req-12345",
    RequestTimestamp = DateTime.UtcNow
};

// Use in service operations
public async Task<Product> GetProductAsync(DbObjectId productId, RequestContext context)
{
    // Multi-tenant data access with context
    // Services can use context.MerchantId for tenant isolation
    // Use context.UserId for auditing and permissions
}

// Admin context
var adminContext = RequestContext.CreateAdmin(userId);

// Correlation tracking
var correlatedContext = RequestContext.WithCorrelation("trace-abc123");

Advanced Features

Model Transformation System

The model transformation system provides flexible, context-aware object transformation capabilities.

using OElite.Common.ModelTransformation;

// Define a custom transformer
public class ProductApiTransformer : IModelTransformer
{
    public Type EntityType => typeof(Product);
    public Type CollectionType => typeof(List<Product>);
    public int Priority => 10;

    public bool CanHandle(TransformationContext context)
    {
        return context.TargetFormat == "api" &&
               context.Properties.ContainsKey("includeInventory");
    }

    public object? TransformObject(object obj, TransformationContext context)
    {
        if (obj is Product product)
        {
            return new ProductApiModel
            {
                Id = product.Id,
                Name = product.Name,
                Price = product.Price,
                // Include inventory only if requested
                Inventory = context.Properties["includeInventory"] as bool? == true
                    ? product.Inventory
                    : null
            };
        }
        return null;
    }

    // Implement other interface members...
}

// Use the transformation system
var context = new TransformationContext
{
    TargetFormat = "api",
    Properties = new Dictionary<string, object>
    {
        ["includeInventory"] = true
    }
};

var transformer = new ProductApiTransformer();
var apiModel = transformer.TransformObject(product, context);

Data Synchronization Jobs

For background data synchronization using RabbitMQ:

using OElite.Common.DataSync;

// Create a data sync job for product updates
var syncJob = new DataSyncJob
{
    EntityType = "Product",
    EntityId = "507f1f77bcf86cd799439011",
    Priority = 3,
    ForceRefresh = false,
    FieldsToRefresh = new[] { "Price", "Inventory", "Categories" },
    Metadata = new Dictionary<string, object>
    {
        ["Source"] = "PriceUpdate",
        ["UpdatedBy"] = "system"
    }
};

// Send to RabbitMQ for processing
// The DataSync runner will pick this up and process it automatically

Path Resolution System

using OElite.Common.Infrastructure;

public class MyPathResolver : IOElitePathResolver
{
    public string ResolvePath(OElitePathType pathType, string relativePath = "")
    {
        return pathType switch
        {
            OElitePathType.Data => Path.Combine("/app/data", relativePath),
            OElitePathType.Logs => Path.Combine("/app/logs", relativePath),
            OElitePathType.Temp => Path.Combine("/tmp", relativePath),
            OElitePathType.Cache => Path.Combine("/app/cache", relativePath),
            _ => relativePath
        };
    }

    public string EnsureDirectory(OElitePathType pathType, string relativePath = "")
    {
        var fullPath = ResolvePath(pathType, relativePath);
        Directory.CreateDirectory(fullPath);
        return fullPath;
    }

    public bool FileExists(OElitePathType pathType, string relativePath)
    {
        return File.Exists(ResolvePath(pathType, relativePath));
    }
}

// Use in your app config
var pathResolver = new MyPathResolver();
var appConfig = new MyAppConfig(jsonConfig, logger, pathResolver);

// Use path operations
var dataPath = appConfig.GetResolvedPath(OElitePathType.Data, "products.json");
var logDir = appConfig.EnsureDirectory(OElitePathType.Logs, "api");
var configExists = appConfig.FileExists(OElitePathType.Config, "settings.json");

Configuration Patterns

JSON Configuration Structure

OElite.Common expects a standardized JSON configuration structure:

{
  "oelite": {
    "data": {
      "mongodb": {
        "platform": "mongodb://mongodb.local:27017/platform",
        "app": "mongodb://mongodb.local:27017/myapp"
      },
      "redis": {
        "platform": "redis.local:6379",
        "app": "localhost:6379"
      }
    },
    "storage": {
      "s3": {
        "platform": "https://s3.amazonaws.com/platform-storage",
        "app": "https://s3.amazonaws.com/app-storage"
      }
    },
    "messages": {
      "twilio": {
        "accountSid": "AC123...",
        "authToken": "abc123...",
        "defaultSmsNumber": "+1234567890",
        "defaultCountryCode": "US"
      },
      "queues": {
        "rabbitmq": {
          "platform": {
            "hostname": "amqp://rabbitmq.local:5672",
            "vhost": "/platform",
            "authUser": "platform_user",
            "authSecret": "secret123"
          }
        }
      }
    },
    "search": {
      "elastic": {
        "platform": {
          "uri": "https://elastic.local:9200",
          "authUser": "elastic",
          "authSecret": "password"
        }
      }
    },
    "authentication": {
      "jwtSecret": "your-secret-key",
      "issuer": "oelite-platform",
      "audience": "oelite-platform",
      "accessTokenExpirationMinutes": 30,
      "refreshTokenExpirationDays": 7
    }
  },
  "nexus": {
    "baseUrl": "https://nexus.local:8080",
    "clientId": "my-app",
    "clientSecret": "client-secret",
    "publicApiKey": "public-key"
  }
}

Application Types

public enum OeAppType
{
    Platform,              // Platform services
    Kortex,               // Kortex proxy services
    Obelisk,              // Mail server
    OeSterling,           // OeSterling services
    GeneralWebApp,        // Web applications
    GeneralWebApi,        // API applications
    GeneralConsoleApp,    // Console applications
    GeneralMobileApp      // Mobile applications
}

Shared Resource Management

OElite.Common optimizes resource usage through shared connection pooling:

// Redis connections are automatically shared based on connection string
var config1 = new MyAppConfig(jsonConfig1);
var config2 = new MyAppConfig(jsonConfig2); // Same Redis connection string

// Both configs will share the same Redis Rest instance
var redis1 = config1.RedisCache;
var redis2 = config2.RedisCache; // Same instance - prevents connection pool exhaustion

// Monitor shared connections
var stats = BaseAppConfig.GetRedisConnectionStats();
Console.WriteLine($"Shared instances: {stats["SharedInstanceCount"]}");

// Cleanup on shutdown
BaseAppConfig.DisposeAllSharedRedisConnections();

Security Features

Claims and Token Management

using OElite.Common.Security;

// Standard OElite claim types
var claims = new[]
{
    new Claim(OEliteClaimTypes.MerchantId, merchantId.ToString()),
    new Claim(OEliteClaimTypes.UserId, userId.ToString()),
    new Claim(OEliteClaimTypes.ContactId, contactId.ToString()),
    new Claim(OEliteClaimTypes.ClientId, "my-client-app"),
    new Claim(ClaimTypes.Role, "admin")
};

// Token response structure
var tokenResponse = new AuthTokenResponse
{
    AccessToken = "jwt-token-here",
    TokenType = "Bearer",
    ExpiresInSeconds = 1800,
    RefreshToken = "refresh-token",
    Scope = "platform:read platform:write"
};

Business Domain Integration

Product Feed Models

using OElite.Common.Biz.ProductFeeds.Requests;
using OElite.Common.Biz.ProductFeeds.Responses;

// Bing Shopping API integration
var bingRequest = new BingShoppingRequest
{
    ProductId = "prod123",
    MerchantId = "merchant456",
    // Additional request properties
};

// Process response
var bingResponse = new BingShoppingResponse
{
    Status = "success",
    Products = new List<BingProduct>(),
    // Response handling
};

Error Handling

using OElite.Common.Exceptions;

// Business-specific exception handling
try
{
    // Business operation
}
catch (OEliteBusinessException ex)
{
    // Handle business logic errors
    logger.LogWarning("Business error: {Message}", ex.Message);
}
catch (OEliteValidationException ex)
{
    // Handle validation errors
    logger.LogError("Validation failed: {Errors}", ex.ValidationErrors);
}

Performance Considerations

Connection Pooling

  • Redis connections are automatically shared and pooled
  • Use BaseAppConfig.GetRedisConnectionStats() for monitoring
  • Call BaseAppConfig.DisposeAllSharedRedisConnections() on application shutdown

Resource Management

  • Rest instances for external services are created lazily
  • Connection strings are cached using hash-based keys
  • Thread-safe shared resource access using ConcurrentDictionary

Memory Optimization

  • Configuration objects are lightweight with lazy resource initialization
  • Model transformers support priority-based processing to avoid unnecessary work
  • Path resolution caching reduces file system calls

Integration with Other OElite Packages

OElite.Common works seamlessly with other OElite packages:

  • OElite.Common.Hosting: Application lifecycle and dependency injection
  • OElite.Common.Hosting.AspNetCore: Web application hosting extensions
  • OElite.Services: Business logic layer with automatic configuration injection
  • OElite.Data.Platform: Data access with shared configuration patterns
  • OElite.Restme: REST client integration with shared connection management

Best Practices

1. Configuration Management

// ✅ DO: Use standardized JSON structure
// ✅ DO: Inherit from BaseAppConfig
// ✅ DO: Implement DbCentreFullClassName for custom data centers
// ❌ DON'T: Create multiple config instances unnecessarily

2. Request Context

// ✅ DO: Always pass RequestContext for tenant operations
// ✅ DO: Use correlation IDs for request tracing
// ✅ DO: Set appropriate context for admin operations
// ❌ DON'T: Perform multi-tenant operations without context

3. Resource Management

// ✅ DO: Use shared Redis connections through configuration
// ✅ DO: Dispose shared connections on application shutdown
// ✅ DO: Monitor connection usage in production
// ❌ DON'T: Create Rest instances manually for configured services

4. Model Transformation

// ✅ DO: Implement priority-based transformers
// ✅ DO: Use context for conditional transformation logic
// ✅ DO: Support both generic and non-generic transformation
// ❌ DON'T: Perform expensive operations in CanHandle checks

Troubleshooting

Common Issues

Configuration Not Loading

// Check JSON structure and property names
var value = JsonConfigParser.GetStringValueOrEmpty(jsonConfig, "oelite:data:mongodb:app");
if (string.IsNullOrEmpty(value))
{
    logger.LogWarning("MongoDB configuration not found for app");
}

Redis Connection Issues

// Monitor shared connections
var stats = BaseAppConfig.GetRedisConnectionStats();
logger.LogInformation("Active Redis connections: {Count}", stats["SharedInstanceCount"]);

// Check connection string format
// Correct: "localhost:6379"
// Correct: "redis://username:password@localhost:6379/0"

Path Resolution Problems

// Ensure path resolver is properly implemented
public class MyPathResolver : IOElitePathResolver
{
    public string ResolvePath(OElitePathType pathType, string relativePath = "")
    {
        // Always return absolute paths
        return pathType switch
        {
            OElitePathType.Data => Path.Combine(_dataRoot, relativePath),
            _ => throw new NotSupportedException($"Path type {pathType} not supported")
        };
    }
}

Version History

  • 5.0.9: Current version with .NET 10.0 support
  • Enhanced shared resource management
  • Improved model transformation system
  • Added comprehensive path resolution
  • Optimized Redis connection pooling

License

Copyright © Phanes Technology Ltd. All rights reserved.

Support

For support and documentation, visit https://www.oelite.com

Showing the top 20 packages that depend on OElite.Common.

Packages Downloads
OElite.Data
Package Description
98
OElite.Common.Hosting
Package Description
97
OElite.Common.Platform
Package Description
97
OElite.Common.Hosting.AspNetCore
Package Description
96
OElite.Services
Package Description
93
OElite.Common.Platform
Package Description
35
OElite.Data
Package Description
34
OElite.Common.Hosting
Package Description
33
OElite.Common.Hosting.AspNetCore
Package Description
32
OElite.Services
Package Description
30
OElite.Data
Package Description
18
OElite.Common.Hosting
Package Description
16
OElite.Common.Hosting.AspNetCore
Package Description
16
OElite.Services
Package Description
16
OElite.Common.Hosting
Package Description
15
OElite.Common.Hosting
Package Description
14
OElite.Common.Hosting.AspNetCore
Package Description
14
OElite.Data
Package Description
14
OElite.Common.Platform
Package Description
13
OElite.Services
Package Description
13

.NET 10.0

Version Downloads Last updated
5.0.9-develop.511 4 11/26/2025
5.0.9-develop.510 3 11/26/2025
5.0.9-develop.509 4 11/23/2025
5.0.9-develop.480 4 11/17/2025
5.0.9-develop.478 3 11/17/2025
5.0.9-develop.477 5 11/17/2025
5.0.9-develop.476 5 11/17/2025
5.0.9-develop.472 5 11/15/2025
5.0.9-develop.471 4 11/15/2025
5.0.9-develop.470 5 11/15/2025
5.0.9-develop.462 4 11/14/2025
5.0.9-develop.448 4 11/11/2025
5.0.9-develop.446 3 11/11/2025
5.0.9-develop.443 4 11/11/2025
5.0.9-develop.441 4 11/09/2025
5.0.9-develop.415 10 10/28/2025
5.0.9-develop.412 4 10/27/2025
5.0.9-develop.411 5 10/27/2025
5.0.9-develop.410 4 10/27/2025
5.0.9-develop.409 4 10/27/2025
5.0.9-develop.402 16 10/26/2025
5.0.9-develop.399 14 10/26/2025
5.0.9-develop.394 15 10/25/2025
5.0.9-develop.391 12 10/25/2025
5.0.9-develop.389 7 10/25/2025
5.0.9-develop.376 32 10/25/2025
5.0.9-develop.374 11 10/24/2025
5.0.9-develop.373 7 10/24/2025
5.0.9-develop.372 7 10/24/2025
5.0.9-develop.259 101 10/20/2025
5.0.9-develop.258 8 10/20/2025
5.0.9-develop.244 5 10/19/2025
5.0.9-develop.240 4 10/18/2025
5.0.9-develop.239 6 10/18/2025
5.0.9-develop.238 10 10/18/2025
5.0.9-develop.236 13 10/18/2025
5.0.9-develop.235 10 10/18/2025
5.0.9-develop.234 10 10/17/2025
5.0.9-develop.227 10 10/17/2025
5.0.9-develop.226 10 10/17/2025
5.0.9-develop.224 11 10/16/2025
5.0.9-develop.222 10 10/16/2025
5.0.9-develop.216 11 10/16/2025
5.0.9-develop.215 9 10/16/2025
5.0.9-develop.212 9 10/15/2025
5.0.9-develop.211 12 10/14/2025
5.0.9-develop.210 11 10/14/2025
5.0.9-develop.209 12 10/14/2025
5.0.9-develop.206 11 10/13/2025
5.0.9-develop.203 9 10/13/2025
5.0.9-develop.61 6 09/17/2025
5.0.9-develop.60 4 09/17/2025
5.0.9-develop.47 6 09/15/2025
5.0.7-ci.1125 8 08/10/2025