VoidCore.Model
17.0.2
dotnet add package VoidCore.Model --version 17.0.2
NuGet\Install-Package VoidCore.Model -Version 17.0.2
<PackageReference Include="VoidCore.Model" Version="17.0.2" />
<PackageVersion Include="VoidCore.Model" Version="17.0.2" />
<PackageReference Include="VoidCore.Model" />
paket add VoidCore.Model --version 17.0.2
#r "nuget: VoidCore.Model, 17.0.2"
#:package VoidCore.Model@17.0.2
#addin nuget:?package=VoidCore.Model&version=17.0.2
#tool nuget:?package=VoidCore.Model&version=17.0.2
VoidCore
VoidCore is a set of core libraries for building business applications on .NET.
FoodStuffs is a comprehensive example of how applications can be built using VoidCore.
Documentation
VoidCore is split into packages so you only get what you need.
| Docs | Description | Release |
|---|---|---|
| VoidCore.Model | An opinionated core for building business applications. | |
| VoidCore.AspNet | Configure ASP.NET web applications based on VoidCore.Model. Includes single-page front end support. | |
| VoidCore.EntityFramework | Entity Framework Core data access for applications based on VoidCore.Model. | |
| VoidCore.Finance | A financial library with primary focus on simple amortization and time-value of money. |
Upgrading
Upgrading to 17.0
Audit and soft-delete timestamps are now always UTC DateTimeOffset values, and time is supplied by .NET's built-in TimeProvider. There is one convention and one set of types.
Removed
IDateTimeService,NowDateTimeService,UtcNowDateTimeService,DiscreteDateTimeService. UseTimeProviderinstead.IAuditableWithOffsetandISoftDeletableWithOffset.IAuditableandISoftDeletablenow useDateTimeOffset.AddAuditabilityWithOffsetandAddSoftDeletabilityWithOffset. UseAddAuditabilityandAddSoftDeletability.- The
DateTimeoverloads ofSetAuditCreated,SetAuditModified, andSetSoftDeleted.
Changed
AddAuditability,AddSoftDeletability, andSetAuditablePropertiestake aTimeProviderinstead of anIDateTimeService.IAuditable.CreatedOn/ModifiedOnandISoftDeletable.DeletedOnareDateTimeOffset(DeletedOnis nullable).SetAuditablePropertiespreviously passed aDateTimeto entities implementingIAuditableWithOffset. It now sets the correct UTC value.ICurrentUserAccessorhas a new synchronousstring GetUserName(). Custom implementations must add it. It should return the same name asGetUser().Loginwithout evaluating policies.
Added
AuditableSaveChangesInterceptorandSoftDeletableSaveChangesInterceptorinVoidCore.EntityFrameworkset audit and soft-delete properties for bothSaveChangesandSaveChangesAsync. They replace overridingSaveChangesin your DbContext. See Entity Framework.ApplySoftDeleteQueryFilter()hides soft-deleted entities from queries.IncludeSoftDeleted()andOnlySoftDeleted()bypass that filter, for example for a recycle bin.SoftDeletableSaveChangesInterceptor.RequireRecycleBinmakes soft-deleting before permanently deleting mandatory.MapHealthEndpoint()inVoidCore.AspNetmaps a/healthendpoint that returns 200 or 503 with each check's description and exception message in a JSON body. See ASP.NET.
Steps
Register a
TimeProviderin dependency injection.services.AddSingleton(TimeProvider.System);Replace
IDateTimeServiceconstructor parameters and fields withTimeProvider.MomentandMomentWithOffsetbecomeGetUtcNow()(which returns a UTCDateTimeOffset).In tests, replace
DiscreteDateTimeServicewithFakeTimeProviderfrom theMicrosoft.Extensions.TimeProvider.Testingpackage.var timeProvider = new FakeTimeProvider(new DateTimeOffset(2001, 2, 12, 0, 0, 0, TimeSpan.Zero));Change entity properties from
DateTimetoDateTimeOffset(andDateTime?toDateTimeOffset?). ReplaceIAuditableWithOffset/ISoftDeletableWithOffsetwithIAuditable/ISoftDeletable.Replace calls to
AddAuditabilityWithOffsetandAddSoftDeletabilityWithOffsetwithAddAuditabilityandAddSoftDeletability.Add an EF migration to convert existing
datetime/datetime2columns todatetimeoffset. Remove anyHasColumnType("datetime")mappings on those properties. Existing values that were stored as local time must be converted to UTC during the migration or they will be misread. Values already stored as UTC can be converted directly.-- Only if values were stored as local time (adjust the time zone name): convert them to UTC first. UPDATE dbo.Recipe SET CreatedOn = CreatedOn AT TIME ZONE 'Central Standard Time' AT TIME ZONE 'UTC'; -- Then convert the column. Existing values are treated as UTC (+00:00). ALTER TABLE dbo.Recipe ALTER COLUMN CreatedOn datetimeoffset NOT NULL;Repeat for each audit and soft-delete column.
Add
GetUserName()to any customICurrentUserAccessorimplementation.If your DbContext overrides
SaveChangesandSaveChangesAsyncto callSetAuditableProperties, remove the overrides and theTimeProviderandICurrentUserAccessorconstructor parameters. Register the interceptors instead. The interceptors are singletons, soICurrentUserAccessorandTimeProvidermust be singletons too.services.AddSingleton<AuditableSaveChangesInterceptor>(); services.AddSingleton<SoftDeletableSaveChangesInterceptor>(); // Only if you use ISoftDeletable. services.AddDbContext<MyDbContext>((provider, options) => options .UseSqlServer(connectionString) .AddInterceptors( provider.GetRequiredService<AuditableSaveChangesInterceptor>(), provider.GetRequiredService<SoftDeletableSaveChangesInterceptor>()));The
AddAuditabilityandAddSoftDeletabilityrepository decorators still work for non-EF repositories but shouldn't be combined with the interceptors.
Developers
VoidCore is built on GitHub Actions and released on Nuget. To release, run the CI workflow manually on main. It builds, pushes to NuGet using trusted publishing, then tags and creates the GitHub release.
To work on VoidCore, you will need the .NET SDK and PowerShell.
See the /build folder for scripts used to test and build this project. Run build.ps1 to make a production build.
./build/build.ps1
There are VSCode tasks for each script. The build task (ctrl + shift + b) performs the standard CI build.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- Microsoft.Extensions.Configuration.Binder (>= 10.0.2)
- Microsoft.Extensions.Hosting (>= 10.0.2)
- Microsoft.Extensions.Logging (>= 10.0.2)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on VoidCore.Model:
| Package | Downloads |
|---|---|
|
VoidCore.AspNet
Configure an ASP.NET web applications based on VoidCore.Model. Includes single-page front end support. |
|
|
VoidCore.EntityFramework
Entity Framework Core data access for applications based on VoidCore.Model. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 17.0.2 | 122 | 10/26/2026 |
| 16.0.7 | 123 | 10/18/2026 |
| 15.3.1 | 544 | 8/3/2025 |
| 15.1.4 | 569 | 4/4/2025 |
| 15.0.1 | 432 | 3/12/2025 |
| 14.1.3 | 504 | 11/18/2024 |
| 14.1.1 | 440 | 10/19/2024 |
| 14.0.5 | 444 | 5/27/2024 |
| 13.0.3 | 459 | 3/22/2024 |
| 12.1.5 | 473 | 2/10/2024 |
| 12.1.2 | 612 | 12/1/2023 |
| 12.1.1 | 487 | 12/1/2023 |
| 12.0.7 | 481 | 11/17/2023 |
| 12.0.6 | 494 | 11/17/2023 |
| 12.0.3 | 496 | 11/15/2023 |
| 11.1.1 | 507 | 11/1/2023 |
| 11.0.6 | 633 | 9/17/2023 |
| 11.0.5 | 654 | 9/16/2023 |
| 11.0.2 | 697 | 8/23/2023 |
| 10.0.4 | 674 | 8/18/2023 |