TCM.Core
1.0.21
dotnet add package TCM.Core --version 1.0.21
NuGet\Install-Package TCM.Core -Version 1.0.21
<PackageReference Include="TCM.Core" Version="1.0.21" />
<PackageVersion Include="TCM.Core" Version="1.0.21" />
<PackageReference Include="TCM.Core" />
paket add TCM.Core --version 1.0.21
#r "nuget: TCM.Core, 1.0.21"
#:package TCM.Core@1.0.21
#addin nuget:?package=TCM.Core&version=1.0.21
#tool nuget:?package=TCM.Core&version=1.0.21
TCM.Core
Shared infrastructure library for the TCM ecosystem. Provides the foundational data access, authentication, caching, validation, auditing, logging, and utility layers consumed by all TCM services.
Features
- Generic Repository Pattern — CRUD operations with paging, stored procedure support, and bulk extensions
- MediatR Pipeline Behaviors — Automatic request validation (FluentValidation) and response caching
- Distributed Caching — Unified interface supporting both Redis and in-memory backends
- Keycloak Integration — OAuth2/OIDC authentication, user management, and UMA permission checks
- JWT Authentication — Pre-configured JWT Bearer setup with API versioning and Swagger
- Audit Logging — Automatic create/update/delete audit trail on all entities
- Excel Import/Export — EPPlus and NPOI based helpers with column attribute mapping
- Barcode Generation — Code128 barcode rendering via ZXing.Net and SkiaSharp
- Serilog Logging — Structured logging to SQL Server and Elasticsearch
- REST Client Helper — Typed HTTP client wrapper for external service calls
- Type Discovery — Reflection-based discovery of classes by interface or base type
- System Settings Module — Shared DB-backed key/value settings with cache, CRUD service, and common controller
Installation
dotnet add package TCM.Core
Requirements
- .NET 7.0 or .NET 9.0
- SQL Server
- Redis (optional — falls back to in-memory cache)
- Keycloak server (optional — for OAuth2/OIDC)
Getting Started
Register Services
// Program.cs
builder.Services.AddTCMCore(builder.Configuration);
This registers:
- EF Core DbContext
- Generic repositories
- Caching services (Redis or memory based on config)
- Keycloak / JWT authentication
- MediatR with validation and caching behaviors
- FluentValidation
- AutoMapper
- Serilog
Shared System Settings
TCM.Core now includes a reusable SystemSetting module for cross-service runtime configuration.
Data model
SystemSetting stores:
FieldName(unique key, ex:Claude.PrimaryModel)FieldValue(string, supports primitive values or JSON payload)Description(optional admin hint)SettingGroup(admin grouping, ex:Claude,Extraction)IsSecret(when true, values are masked in API responses)
Contracts
ISystemSettingResolverfor runtime reads:GetStringAsync,GetIntAsync,GetDecimalAsync,GetBoolAsync,GetJsonAsync<T>GetGroupAsync
ISystemSettingCrudServicefor admin CRUD/upsert operationsISystemSettingDbContextfor host DbContext integration
Registration
In host modules, register shared settings once:
services.AddSystemSettingShared(configuration);
services.AddScoped<ISystemSettingDbContext>(sp => sp.GetRequiredService<YourDbContext>());
AddSystemSettingShared registers:
SystemSettingServiceISystemSettingResolverISystemSettingCrudServiceSystemSettingOptions(SystemSetting:CacheMinutes, default 30)
Common API Controller
TCM.Core.Controllers.v1.SystemSettingsController provides:
GET /api/v1/SystemSettingsGET /api/v1/SystemSettings/{fieldName}POST /api/v1/SystemSettingsPUT /api/v1/SystemSettings/{fieldName}DELETE /api/v1/SystemSettings/{fieldName}POST /api/v1/SystemSettings/upsert
To expose shared controller assembly in host apps:
builder.Services.AddControllers()
.AddCoreSharedControllers();
Cache behavior
- Cache key pattern:
SystemSetting:Key:{fieldName}SystemSetting:Group:{settingGroup}
- Reads are cache-first, then DB fallback
- Writes invalidate related key/group cache entries
Configuration
{
"CacheSettings": {
"RedisUrl": "localhost:6379",
"Password": "",
"Ssl": false,
"UseMemoryCache": false
},
"KeycloakSettings": {
"ServerUrl": "https://auth.example.com",
"Realm": "tcm",
"ClientId": "tcm-api",
"AdminUsername": "admin",
"AdminPassword": "admin"
}
}
Define an Entity
public class Product : BaseEntity
{
public string Name { get; set; }
public decimal Price { get; set; }
}
BaseEntity provides: Id (Guid), IsActive, CreatedDate, CreatedUserId, ModifiedDate, ModifiedUserId.
Use a Repository
public class ProductService
{
private readonly IGenericRepositoryAsync<Product> _repository;
public ProductService(IGenericRepositoryAsync<Product> repository)
{
_repository = repository;
}
public async Task<Product> GetByIdAsync(Guid id)
=> await _repository.GetByIdAsync(id);
public async Task<IReadOnlyList<Product>> GetAllAsync()
=> await _repository.GetAllAsync();
}
Cacheable MediatR Query
public class GetProductQuery : IRequest<Response<ProductDto>>, ICacheableMediatrQuery
{
public Guid Id { get; set; }
public bool BypassCache { get; set; }
public string CacheKey => $"Product_{Id}";
public TimeSpan? SlidingExpiration => TimeSpan.FromMinutes(10);
}
Excel Export
public class ProductExcelModel : BaseExcelModel
{
[ExcelColumn("Product Name", 1)]
public string Name { get; set; }
[ExcelColumn("Price", 2)]
public decimal Price { get; set; }
}
var bytes = ExportExcelHelper.Export(products);
Project Structure
TCM.Core/
├── Controllers/ # Shared API controllers (e.g. SystemSettingsController)
├── Attributes/ # Custom ASP.NET attributes (Permission, ForbidError)
├── Audits/ # Audit trail service
├── Behaviours/ # MediatR pipeline behaviors (Validation, Caching)
├── Caching/ # ICachingService, Redis/Memory implementation
├── Contexts/ # TCDbContext (abstract EF Core base), ElasticContext
├── Converters/ # JSON converters (DateOnly, TimeOnly)
├── Definitions/ # Business enums and constants
├── EntityConfigurations/ # EF Core Fluent API base configurations
├── Exceptions/ # ApiException, ValidationException
├── Extensions/ # String, DateTime, QueryableExtensions + DI setup
├── Helpers/ # Excel, Barcode, REST client, TypeFinder, etc.
├── Logging/ # TCLog static facade
├── Middlewares/ # ErrorHandlerMiddleware
├── Models/ # BaseEntity, Response<T>, PagedResponse<T>, DTOs
├── Repositories/ # IGenericRepositoryAsync + implementations
├── Services/ # IAuthenticatedUserService, IKeycloakService, system setting services
└── Settings/ # CacheSettings, KeycloakSettings, SystemSettingOptions
Key Dependencies
| Package | Purpose |
|---|---|
| Microsoft.EntityFrameworkCore | ORM and database access |
| EFCore.BulkExtensions | High-performance bulk insert/update/delete |
| MediatR | CQRS / mediator pattern |
| FluentValidation | Request validation |
| AutoMapper | Object mapping |
| Microsoft.AspNetCore.Authentication.JwtBearer | JWT authentication |
| StackExchange.Redis | Distributed cache |
| Serilog | Structured logging |
| Elastic.Clients.Elasticsearch | Elasticsearch integration |
| EPPlus / NPOI | Excel file handling |
| ZXing.Net + SkiaSharp | Barcode generation |
| Swashbuckle.AspNetCore | Swagger / OpenAPI docs |
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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 is compatible. 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. |
-
net7.0
- AutoMapper (>= 16.1.1)
- EFCore.BulkExtensions (>= 7.8.1)
- Elastic.Clients.Elasticsearch (>= 8.19.22)
- Elastic.Serilog.Sinks (>= 8.19.0)
- EPPlus (>= 8.5.0)
- FluentValidation (>= 11.9.2)
- FluentValidation.DependencyInjectionExtensions (>= 11.9.2)
- MediatR (>= 12.4.1)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 7.0.20)
- Microsoft.AspNetCore.Http.Abstractions (>= 2.3.9)
- Microsoft.AspNetCore.Mvc.Versioning (>= 5.1.0)
- Microsoft.Data.SqlClient (>= 5.2.2)
- Microsoft.EntityFrameworkCore (>= 7.0.20)
- Microsoft.EntityFrameworkCore.SqlServer (>= 7.0.20)
- Microsoft.Extensions.Caching.Memory (>= 8.0.1)
- Microsoft.Extensions.Caching.StackExchangeRedis (>= 7.0.20)
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.IdentityModel.Protocols.OpenIdConnect (>= 8.14.0)
- Newtonsoft.Json (>= 13.0.4)
- NPOI (>= 2.7.6)
- Serilog (>= 4.3.1)
- Serilog.AspNetCore (>= 7.0.0)
- Serilog.Sinks.MSSqlServer (>= 7.0.2)
- SkiaSharp (>= 3.119.2)
- SkiaSharp.NativeAssets.Linux (>= 3.119.2)
- Swashbuckle.AspNetCore (>= 6.5.0)
- System.IdentityModel.Tokens.Jwt (>= 8.14.0)
- ZXing.Net (>= 0.16.11)
- ZXing.Net.Bindings.SkiaSharp (>= 0.16.22)
-
net9.0
- AutoMapper (>= 16.1.1)
- EFCore.BulkExtensions (>= 9.0.2)
- Elastic.Clients.Elasticsearch (>= 8.19.22)
- Elastic.Serilog.Sinks (>= 8.19.0)
- EPPlus (>= 8.5.0)
- FluentValidation (>= 12.1.1)
- FluentValidation.DependencyInjectionExtensions (>= 12.1.1)
- MediatR (>= 14.1.0)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 9.0.14)
- Microsoft.AspNetCore.Http.Abstractions (>= 2.3.9)
- Microsoft.AspNetCore.Mvc.Versioning (>= 5.1.0)
- Microsoft.Data.SqlClient (>= 6.1.2)
- Microsoft.EntityFrameworkCore (>= 9.0.14)
- Microsoft.EntityFrameworkCore.SqlServer (>= 9.0.14)
- Microsoft.Extensions.Caching.Memory (>= 10.0.5)
- Microsoft.Extensions.Caching.StackExchangeRedis (>= 10.0.5)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.5)
- Microsoft.IdentityModel.Protocols.OpenIdConnect (>= 8.14.0)
- Newtonsoft.Json (>= 13.0.4)
- NPOI (>= 2.7.6)
- Serilog (>= 4.3.1)
- Serilog.AspNetCore (>= 10.0.0)
- Serilog.Sinks.MSSqlServer (>= 9.0.3)
- SkiaSharp (>= 3.119.2)
- SkiaSharp.NativeAssets.Linux (>= 3.119.2)
- Swashbuckle.AspNetCore (>= 10.1.5)
- System.IdentityModel.Tokens.Jwt (>= 8.14.0)
- ZXing.Net (>= 0.16.11)
- ZXing.Net.Bindings.SkiaSharp (>= 0.16.22)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on TCM.Core:
| Package | Downloads |
|---|---|
|
TCM.InAppAuth
In-App Authentication library for TCM projects. |
|
|
TCM.Tasks
Task scheduling library for TCM projects, built on Quartz.NET. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.21 | 0 | 6/8/2026 |
| 1.0.20 | 47 | 6/6/2026 |
| 1.0.19 | 44 | 6/6/2026 |
| 1.0.18 | 197 | 6/2/2026 |
| 1.0.17 | 136 | 6/2/2026 |
| 1.0.16 | 244 | 5/26/2026 |
| 1.0.15 | 290 | 5/24/2026 |
| 1.0.14 | 155 | 5/24/2026 |
| 1.0.13 | 138 | 5/24/2026 |
| 1.0.11 | 163 | 5/24/2026 |
| 1.0.10 | 118 | 5/24/2026 |
| 1.0.9 | 154 | 5/24/2026 |
| 1.0.8 | 224 | 5/23/2026 |
| 1.0.6 | 208 | 5/23/2026 |
| 1.0.5 | 90 | 5/22/2026 |
| 1.0.4 | 113 | 5/19/2026 |
| 1.0.3 | 144 | 5/15/2026 |
| 1.0.2 | 187 | 3/23/2026 |
| 1.0.1 | 122 | 3/18/2026 |
| 1.0.0 | 113 | 3/18/2026 |