Aspireng.Infrastructure
1.1.3
dotnet add package Aspireng.Infrastructure --version 1.1.3
NuGet\Install-Package Aspireng.Infrastructure -Version 1.1.3
<PackageReference Include="Aspireng.Infrastructure" Version="1.1.3" />
<PackageVersion Include="Aspireng.Infrastructure" Version="1.1.3" />
<PackageReference Include="Aspireng.Infrastructure" />
paket add Aspireng.Infrastructure --version 1.1.3
#r "nuget: Aspireng.Infrastructure, 1.1.3"
#:package Aspireng.Infrastructure@1.1.3
#addin nuget:?package=Aspireng.Infrastructure&version=1.1.3
#tool nuget:?package=Aspireng.Infrastructure&version=1.1.3
Aspireng.Infrastructure
Purpose: Pluggable repository implementations and cross-cutting adapters that back the domain abstractions.
Includes:
- Repositories: In-Memory, File, EF Core
- Encryption:
IEntityProtector
+NoOpEntityProtector
- Caching adapter:
MemoryCacheAppCache
(implementsIAppCache
) - DI Extensions: one-liners to register preferred storage per microservice
Repositories
InMemoryRepository<T>
- Thread-safe
ConcurrentDictionary
. - Great for tests/dev or ephemeral data.
- Evaluates specifications in memory.
FileRepository<T>
- One JSON file per entity (
*.stone
). - Per-file
SemaphoreSlim
for process-local concurrency. - Evaluates specifications in memory.
- Options
services.AddFileRepositories(o => o.RootDirectory = "App_Data");
⚠️ If multiple processes write to the same directory, consider a distributed lock or avoid sharing directories.
EfRepository<T>
- Translates specifications to SQL via EF Core.
- Requires a registered
DbContext
in DI. - Uses
AsNoTracking()
for reads; callUpdate
/AddAsync
for writes.
Encryption
Implement IEntityProtector
to bridge your existing EncryptAllField
/DecryptAllField
logic:
public sealed class MyEntityProtector : IEntityProtector
{
public void Encrypt<T>(T entity) { /* call your encryption helpers */ }
public void Decrypt<T>(T entity) { /* call your decryption helpers */ }
}
Register it instead of NoOpEntityProtector
.
Caching Adapter
MemoryCacheAppCache
wraps IMemoryCache
and implements IAppCache
.
services.AddBuildingBlocksCaching(); // adds IMemoryCache + IAppCache
If you already use IIsolatedCache
, create an adapter that implements IAppCache
.
DI Registration
Use the extensions in Extensions/RepositoryRegistration.cs
.
using Microsoft.EntityFrameworkCore;
using Aspireng.Infrastructure.Extensions;
using Aspireng.Infrastructure.Persistence.File;
// using Aspireng.Infrastructure.Persistence.EfCore;
// Add cache adapter
services.AddBuildingBlocksCaching();
// Choose ONE global default:
services.AddFileRepositories(o => o.RootDirectory = builder.Configuration["Persistence:RootDirectory"] ?? "App_Data");
// or EF Core:
// services.AddDbContext<AppDbContext>(opt => opt.UseSqlServer(cfg.GetConnectionString("Default")));
// services.AddEfRepositories();
// or In-Memory:
// services.AddInMemoryRepositories();
// Per-aggregate overrides are allowed:
services.AddScoped<IRepository<MyEntity>, EfRepository<MyEntity>>();
Using From a Microservice
// Program.cs
builder.Services.AddBuildingBlocksCaching();
builder.Services.AddFileRepositories(o => o.RootDirectory = "App_Data");
// Application service
builder.Services.AddScoped<OrderService>(); // your service inheriting ReadWriteService<Order>
Concurrency & Consistency
- Optimistic concurrency: add a
RowVersion
(byte[]
) to your service’s entities and configure EF with[Timestamp]
. - File repository: per-file locks are per-process only. For cross-process access, prefer EF Core or introduce a distributed lock.
Pack
./build/release-aspireng.cmd
The package id should be Aspireng.Infrastructure
.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | 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. |
-
net9.0
- Aspireng.Application (>= 1.1.3)
- Aspireng.Domain (>= 1.1.3)
- Microsoft.EntityFrameworkCore (>= 9.0.8)
- Microsoft.Extensions.Caching.Abstractions (>= 9.0.8)
- Microsoft.Extensions.Caching.Memory (>= 9.0.8)
- Microsoft.Extensions.Configuration (>= 9.0.8)
- Microsoft.Extensions.Configuration.Abstractions (>= 9.0.8)
- Microsoft.Extensions.Configuration.Binder (>= 9.0.8)
- Microsoft.Extensions.Configuration.CommandLine (>= 9.0.8)
- Microsoft.Extensions.Configuration.EnvironmentVariables (>= 9.0.8)
- Microsoft.Extensions.Configuration.FileExtensions (>= 9.0.8)
- Microsoft.Extensions.Configuration.Json (>= 9.0.8)
- Microsoft.Extensions.DependencyInjection (>= 9.0.8)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.8)
- Microsoft.Extensions.Hosting (>= 9.0.8)
- Microsoft.Extensions.Hosting.Abstractions (>= 9.0.8)
- Microsoft.Extensions.Logging (>= 9.0.8)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.8)
- Microsoft.Extensions.Options (>= 9.0.8)
- Microsoft.Extensions.Options.DataAnnotations (>= 9.0.8)
- Microsoft.SourceLink.GitHub (>= 8.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.