XSmart.BuildingBlocks
1.0.49
dotnet add package XSmart.BuildingBlocks --version 1.0.49
NuGet\Install-Package XSmart.BuildingBlocks -Version 1.0.49
<PackageReference Include="XSmart.BuildingBlocks" Version="1.0.49" />
<PackageVersion Include="XSmart.BuildingBlocks" Version="1.0.49" />
<PackageReference Include="XSmart.BuildingBlocks" />
paket add XSmart.BuildingBlocks --version 1.0.49
#r "nuget: XSmart.BuildingBlocks, 1.0.49"
#:package XSmart.BuildingBlocks@1.0.49
#addin nuget:?package=XSmart.BuildingBlocks&version=1.0.49
#tool nuget:?package=XSmart.BuildingBlocks&version=1.0.49
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 clientRestClientWithRetry: Implementation with retry logicRequestOptions: Flexible configuration objectRetryPolicyFactory: 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: ExtractsSiteheader and sets it inSiteContextISiteProvider: Interface to retrieve the current siteSiteContext: 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
TaskorTask<T>. - Consider handling exceptions using
GoogleDriveProviderExceptionor standardIOException.
π§© 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):
- Implement
IStorageProvider - Register it via configuration
- 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
IRestClientanywhere you consume 3rd-party APIs or internal services - Inject
ClaimsPrincipal(viaHttpContext.User) into services to access current user info - Customize retry count and backoff as needed using Polly policies
- Always include
Siteheader for multi-site-aware APIs - Use
FileUtilfor 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 | Versions 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. |
-
net8.0
- Azure.Storage.Blobs (>= 12.24.1)
- Google.Apis.Drive.v3 (>= 1.70.0.3834)
- Microsoft.AspNetCore.Http.Abstractions (>= 2.3.0)
- Microsoft.Windows.Compatibility (>= 8.0.18)
- Polly (>= 8.6.1)
- SSH.NET (>= 2025.0.0)
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 |