XSmart.BuildingBlocks 1.0.49

dotnet add package XSmart.BuildingBlocks --version 1.0.49
                    
NuGet\Install-Package XSmart.BuildingBlocks -Version 1.0.49
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="XSmart.BuildingBlocks" Version="1.0.49" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="XSmart.BuildingBlocks" Version="1.0.49" />
                    
Directory.Packages.props
<PackageReference Include="XSmart.BuildingBlocks" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add XSmart.BuildingBlocks --version 1.0.49
                    
#r "nuget: XSmart.BuildingBlocks, 1.0.49"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package XSmart.BuildingBlocks@1.0.49
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=XSmart.BuildingBlocks&version=1.0.49
                    
Install as a Cake Addin
#tool nuget:?package=XSmart.BuildingBlocks&version=1.0.49
                    
Install as a Cake Tool

XSmart.BuildingBlocks

This package provides reusable components to accelerate the development of scalable, high-performance applications and utilities for building maintainable and resilient solutions within the XSmart ecosystem, enabling seamless integration and enhanced functionality.


πŸš€ 1. Resilient REST Client with Retry Support

A customizable HTTP client wrapper using Polly for resilience and built-in retry capabilities.

βœ… Key Components

  • IRestClient: Interface to abstract the client
  • RestClientWithRetry: Implementation with retry logic
  • RequestOptions: Flexible configuration object
  • RetryPolicyFactory: Provides a default exponential backoff policy

πŸ›  Usage

1. Register IRestClient in DI
builder.Services.AddHttpClient<IRestClient, RestClientWithRetry>();
2. Create RequestOptions and Call
var requestOptions = new RequestOptions
{
    Url = "https://api.example.com/data",
    Method = HttpMethod.Get,
    Token = "your-jwt-token",
    RetryPolicy = RetryPolicyFactory.CreateDefaultPolicy(), // Optional
    Headers = new Dictionary<string, string>
    {
        ["Site"] = "Thailand"
    }
};

string response = await _restClient.SendAsync(requestOptions);
Example: Sending a POST request with payload
using XSmart.BuildingBlocks.Common.Http;
using System.Net.Http;
using System.Threading.Tasks;

public class MyService
{
    private readonly IRestClient _restClient;

    public MyService(IRestClient restClient)
    {
        _restClient = restClient;
    }

    public async Task SendData()
    {
        var requestOptions = new RequestOptions
        {
            Url = "https://api.example.com/endpoint",
            Method = HttpMethod.Post,
            Payload = "{ "name": "value" }",
            Token = "your-token-here",
            RetryPolicy = RetryPolicyFactory.CreateDefaultPolicy()
        };

        var response = await _restClient.SendAsync(requestOptions);
    }
}

πŸ“† Retry Policy

You can create your own, or use the default:

var retry = RetryPolicyFactory.CreateDefaultPolicy();
This policy:
  • Retries 3 times
  • Waits exponentially (2s, 4s, 8s)
  • Logs retry reasons

πŸ§‘β€πŸ’Ό 2. JWT Claims Helper for ClaimsPrincipal

Simplifies access to common claims from authenticated users.

✨ Extension Methods

string? name = User.GetName();
string? userId = User.GetNameIdentifier();
string? email = User.GetEmail();
string? role = User.GetRole();

🌟 Get App Roles

If your token includes appRoles as a serialized JSON string:

"appRoles": "{"WMS":"Admin","Finance":"Viewer"}"

Use this helper:

var roles = User.GetAppRoles();
var wmsRole = roles["WMS"];  // "Admin"
Example: Extracting the User’s Email and Role in your controller
using XSmart.BuildingBlocks.Common.Extensions;

[Authorize]
[HttpGet("me")]
public IActionResult GetLoggedInUserInfo()
{
    var email = User.GetEmail();
    var role = User.GetRole();
    var appRoles = User.GetAppRoles();

    var userDetails = new
    {
        Email = email,
        Role = role,
        AppRoles = appRoles
    };

    return Ok(userDetails);
}

πŸ—‚ 3. File Utilities

Provides file management utilities like renaming files if they already exist and calculating file MD5 hashes.

βœ… Key Methods

  • RenameFileIfExist: Renames a file if a file with the same name already exists in the specified directory.
  • FileMD5: Calculates the MD5 hash of a file to verify integrity or detect changes.

πŸ›  Usage

1. Rename a file if it exists
var newFileName = FileUtil.RenameFileIfExist("example.txt");

This will append a number to the file name, ensuring there is no conflict with existing files.

2. Calculate MD5 hash of a file
string md5Hash = FileUtil.FileMD5("path/to/file.txt");

This will return the MD5 hash of the file as a hexadecimal string.


πŸ—‚ 4. File Validation

This component provides a flexible and extensible way to validate files (e.g., PDF, CSV) based on their content and file extension.

πŸ›  Usage

1. Register Validators in Dependency Injection

In your Startup.cs or Program.cs:

services.AddScoped<IFileValidator, PdfFileValidator>();
services.AddScoped<IFileValidator, CsvFileValidator>();
services.AddSingleton<FileValidatorResolver>();

This will append a number to the file name, ensuring there is no conflict with existing files.

2. Example Usage

In a controller or service:

public class FileValidationService
{
    private readonly FileValidatorResolver _resolver;

    public FileValidationService(FileValidatorResolver resolver)
    {
        _resolver = resolver;
    }

    public bool Validate(IFormFile file)
    {
        var validator = _resolver.Resolve(file.FileName);
        if (validator == null) return false;

        using var stream = file.OpenReadStream();
        return validator.IsValidContent(stream);
    }
}

This will return the MD5 hash of the file as a hexadecimal string.


🌍 5. Multi-Site Support

Provides context-aware site handling for multi-tenant systems using headers and scoped services.

βœ… Key Components

  • SiteMiddleware: Extracts Site header and sets it in SiteContext
  • ISiteProvider: Interface to retrieve the current site
  • SiteContext: Scoped class holding the current site info

πŸ›  Usage

1. Register middleware and DI
builder.Services.AddScoped<SiteContext>();
builder.Services.AddScoped<ISiteProvider, ContextSiteProvider>();

app.UseSiteHeader();
2. Access in controller or service
using XSmart.BuildingBlocks.SharedKernel.MultiSite;
using Microsoft.AspNetCore.Mvc;

public class SampleController(ISiteProvider siteProvider) : ControllerBase
{
    [HttpGet("site")]
    public IActionResult GetSiteInfo()
    {
        var site = siteProvider.GetCurrentSite() ;
        return Ok(site);
    }
}

OR

public class MyService
{
    private readonly ISiteProvider _siteProvider;
    
    public MyService(ISiteProvider siteProvider)
    {
        _siteProvider = siteProvider;
    }

    public void DoWork()
    {
        var site = _siteProvider.GetCurrentSite(); // e.g., "Thailand"
    }
}

πŸ“Œ HTTP Header Requirement

Every API call should include:

Site: TH

πŸ“¦ 6. IStorageProvider – Integration Storage

This module provides a unified abstraction for different file storage providers such as local shared drives and Google Drive. It defines a common interface IStorageProvider and concrete implementations like SharedDriveStorageProvider and GoogleDriveStorageProvider.


βœ… Supported Providers

Provider Class Description
Shared Drive SharedDriveStorageProvider Access files in a local/network path
Google Drive GoogleDriveStorageProvider Access files via Google Drive API
SFTP SftpStorageProvider Access files via SFTP

πŸ”§ How to Use

1. Register the Provider

You can register a storage provider based on configuration or runtime decision.

IStorageProvider storageProvider = new SharedDriveStorageProvider();
// or
IStorageProvider storageProvider = new GoogleDriveStorageProvider("service-account.json");

2. List Files

var files = await storageProvider.ListFilesAsync("path");
foreach (var file in files)
{
    Console.WriteLine(file);
}

3. Download a File

await storageProvider.DownloadFileAsync("sourcePath", "destinationPath");

4. Upload a File

await storageProvider.UploadFileAsync("sourcePath", "destinationPath");

5. Delete a File

await storageProvider.DeleteFileAsync("path");

6. Delete Files Older Than X Days

await storageProvider.DeleteFilesOlderThanAsync("path", TimeSpan.FromDays(30));

πŸ“‚ Examples

πŸ”Ή Shared Drive Example

var storageOptions = new SharedDriveStorageOptions
{
    NetworkPath = @"\\NetworkSharePath",
    Username = "your-username",
    Password = "your-password",
    Domain = "your-domain"               // Optional
};

using (var storageProvider = new SharedDriveStorageProvider(storageOptions))
{
    try
    {
        // Specify paths for file download and upload
        string downloadSourcePath = @"\\NetworkSharePath\fileToDownload.txt";
        string downloadDestinationPath = @"C:\LocalPath\downloadedFile.txt";
        string uploadSourcePath = @"C:\LocalPath\fileToUpload.txt";
        string uploadDestinationPath = @"\\NetworkSharePath\uploadedFile.txt"; 
        
        // Download file asynchronously
        await storageProvider.DownloadFileAsync(downloadSourcePath, downloadDestinationPath);

        // Upload file asynchronously
        await storageProvider.UploadFileAsync(uploadSourcePath, uploadDestinationPath);
    }
    catch (SharedDriveProviderException ex)
    {
        Console.WriteLine($"An error occurred: {ex.Message}");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"An unexpected error occurred: {ex.Message}");
    }
}

πŸ”Ή Google Drive Example

var provider = new GoogleDriveStorageProvider("google-credentials.json");
await provider.UploadFileAsync(@"C:\Temp\report.pdf", "google-drive-folder-id");

πŸ”Ή SFTP Example

SftpStorageOptions storageOptions = new SftpStorageOptions
{
    BasePath = "your-path",
    Host = "your-ftp-server",
    Port = 22,
    Username = "your-username",
    Password = "your-password"
};

IStorageProvider storageProvider = new SftpStorageProvider(storageOptions);
await storageProvider.UploadFileAsync(tempFilePath, file.FileName);


⚠️ Notes

  • GoogleDrive uses the Google Service Account JSON file.
  • All methods are asynchronous and return Task or Task<T>.
  • Consider handling exceptions using GoogleDriveProviderException or standard IOException.

🧩 Interface Definition

public interface IStorageProvider
{
    StorageProviderType ProviderType { get; }

    Task<IEnumerable<string>> ListFilesAsync(string pathOrId);
    Task DownloadFileAsync(string sourcePathOrId, string destinationPath);
    Task UploadFileAsync(string sourcePath, string destinationPathOrId);
    Task DeleteFileAsync(string pathOrId);
    Task DeleteFilesOlderThanAsync(string folderPathOrId, TimeSpan maxAge);
}

πŸ›‘οΈ Exception Handling

Wrap your calls in try-catch for safety:

try
{
    await storageProvider.UploadFileAsync("file.txt", "target-folder");
}
catch (GoogleDriveProviderException ex)
{
    // Log or handle
}

πŸ—οΈ Extendability

To add a new provider (e.g., Azure Blob, AWS S3):

  1. Implement IStorageProvider
  2. Register it via configuration
  3. Follow the same method contract

πŸ”— Summary

Feature Purpose
RestClientWithRetry Make resilient REST calls with retry logic
RequestOptions Fully configurable HTTP request options
ClaimsPrincipalExtensions Simple access to JWT claims (Name, Email, Roles, AppRoles)
RetryPolicyFactory Provides a ready-to-use retry strategy using Polly
SiteContext, ISiteProvider, SiteMiddleware Enable site-aware multi-tenant logic
FileUtil Utilities for file management (renaming and MD5 hash)
IStorageProvider A unified abstraction for different file storage providers

πŸ“‚ Recommendations

  • Use IRestClient anywhere you consume 3rd-party APIs or internal services
  • Inject ClaimsPrincipal (via HttpContext.User) into services to access current user info
  • Customize retry count and backoff as needed using Polly policies
  • Always include Site header for multi-site-aware APIs
  • Use FileUtil for file management tasks such as renaming files and calculating MD5 hashes

πŸ“¦ NuGet Package Information

  • Package Name: XSmart.BuildingBlocks

πŸ“₯ Installation

You can install the XSmart.BuildingBlocks library from NuGet:

Or use the NuGet Package Manager in Visual Studio.


πŸ“ License

⚠️ This software is proprietary and is provided for internal use only.

Unauthorized distribution or use outside the organization is prohibited.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.49 100 4/3/2026
1.0.48 297 3/17/2026
1.0.47 99 3/17/2026
1.0.46 98 3/16/2026
1.0.45 104 3/16/2026
1.0.44 110 3/16/2026
1.0.43 317 1/15/2026
1.0.42 362 10/30/2025
1.0.41 244 9/30/2025
1.0.40 289 8/6/2025
1.0.39 147 7/31/2025
1.0.38 193 7/9/2025
1.0.37 332 6/11/2025
1.0.36 329 6/11/2025
1.0.35 200 6/5/2025
1.0.34 191 6/5/2025
1.0.33 185 6/5/2025
1.0.32 180 6/4/2025
1.0.31 183 6/4/2025
1.0.30 189 6/2/2025
Loading failed