Tooark.Entities
4.7.0
See the version list below for details.
dotnet add package Tooark.Entities --version 4.7.0
NuGet\Install-Package Tooark.Entities -Version 4.7.0
<PackageReference Include="Tooark.Entities" Version="4.7.0" />
<PackageVersion Include="Tooark.Entities" Version="4.7.0" />
<PackageReference Include="Tooark.Entities" />
paket add Tooark.Entities --version 4.7.0
#r "nuget: Tooark.Entities, 4.7.0"
#:package Tooark.Entities@4.7.0
#addin nuget:?package=Tooark.Entities&version=4.7.0
#tool nuget:?package=Tooark.Entities&version=4.7.0
Tooark.Entities
Library with base entities for .NET applications, including support for unique identifiers, auditing, versioning and soft delete.
π Languages: πΊπΈ English (this file) Β· π§π· PortuguΓͺs
π Contents
- Package Contents
- Installation
- Configuration
- Entities (Details)
- Usage Examples
- Dependencies
- Error Codes, Notifications and Solutions
- Contributing
- Help & Security
- Support
- License
π¦ Package Contents
Entities
| Class | Description |
|---|---|
BaseEntity |
Unique identifier + notification/validation support |
InitialEntity |
Creation information (CreatedById/CreatedAt) |
DetailedEntity |
Update information (UpdatedById/UpdatedAt) |
VersionedEntity |
Versioning (Version) incremented on updates |
SoftDeletableEntity |
Simple soft delete (Deleted) + update through UpdatedById |
AuditableEntity |
Full auditing: version (Version) + deletion (Deleted)/restoration with user/date (DeletedById/DeletedAt/RestoredById/RestoredAt) |
FileEntity |
Base entity for files (FileName, Title, Link, FileFormat, Type, Size) |
Value Objects used by the entities
The entities receive Value Objects from the Tooark.ValueObjects package β CreatedBy, UpdatedBy,
DeletedBy, RestoredBy, FileStorage and Title β and keep the already converted value. What goes in
is the value object (CreatedBy); what the entity exposes is the Guid (CreatedById).
π§ Installation
dotnet add package Tooark.Entities
βοΈ Configuration
There is no additional configuration.
How write operations react to an invalid value
The Set* methods throw BadRequestException and leave no notification on the entity. A rejected
call changes nothing: the entity stays intact and the next call, if correct, is accepted normally.
using Tooark.Entities;
using Tooark.Exceptions;
public static class Example
{
public static void Delete(AuditableEntity entity, Guid user)
{
try
{
// Rejected: the identifier is empty
entity.SetDeleted(Guid.Empty);
}
catch (BadRequestException)
{
// The entity kept nothing from the rejected call and stays intact
}
// Accepted normally
entity.SetDeleted(user);
}
}
The exception for a missing value differs from the one for an invalid value: null produces
Field.Required;<field>, and a value that is present but rejected produces Field.Invalid;<field>.
BaseEntity.SetId is the only exception: it accumulates a notification instead of throwing, because it
runs in the constructor. Check IsValid after building an entity with a provided identifier.
ValidateNotDeleted(), on the other hand, accumulates a notification on purpose β it is the method to check
without interrupting the flow. To interrupt, use EnsureNotDeleted(), which throws.
π§© Entities (Details)
BaseEntity
- Properties
Id(Guid) β columnid(uuid)
- Constructors (for derived classes)
BaseEntity()β generatesIdautomaticallyBaseEntity(Guid id)β sets a deterministicId(seed/tests/factories)
- Notes
Idhas a private setter. Derived classes set the identifier through the protectedSetId, which rejectsGuid.Emptyand rejects changing the identity of an already created entity β in both cases by notification, without throwing.- Equality compares type and identifier: entities of different types with the same
Idare not equal. The comparison accepts inheritance in both directions, so it does not break with Entity Framework lazy-loading proxies. - Usage Examples.
InitialEntity
- Properties
CreatedById(Guid) β columncreated_by(uuid)CreatedAt(DateTime/UTC) β columncreated_at(timestamp with time zone)
- Methods
SetCreatedBy(CreatedBy createdById)
- Notes
- Inherits from
BaseEntity. SetCreatedByreceives theCreatedByValue Object, which accepts implicit conversion fromGuid.- On invalid data, throws
BadRequestException. - Usage Examples.
- Inherits from
DetailedEntity
- Properties
UpdatedById(Guid) β columnupdated_by(uuid)UpdatedAt(DateTime/UTC) β columnupdated_at(timestamp with time zone)
- Methods
SetCreatedBy(CreatedBy createdById)β also setsUpdatedByIdandUpdatedAt, equal to the creation onesSetUpdatedBy(UpdatedBy updatedById)
- Notes
- Inherits from
InitialEntity. SetUpdatedByreceives theUpdatedByValue Object, which accepts implicit conversion fromGuid.- On invalid data, throws
BadRequestException. - Usage Examples.
- Inherits from
VersionedEntity
- Properties
Version(long) β columnversion(bigint), default value1
- Methods
SetUpdatedBy(UpdatedBy updatedById)β updates and increments the version
- Notes
- Inherits from
DetailedEntity. - On invalid data, throws
BadRequestException. - Usage Examples.
- Inherits from
SoftDeletableEntity
- Properties
Deleted(bool) β columndeleted(bool), default valuefalse
- Methods
ValidateNotDeleted()β validates that it is not deleted and adds a notificationEnsureNotDeleted()β throws an exception if it is deletedSetDeleted(UpdatedBy changedById)β marks as deleted and updates; ignored if already deletedSetRestored(UpdatedBy changedById)β restores and updates; ignored if not deleted
- Notes
- Inherits from
DetailedEntity. - On invalid data, throws
BadRequestException. - Usage Examples.
- Inherits from
AuditableEntity
- Properties
Version(long)Deleted(bool)DeletedById(Guid?) β columndeleted_by(uuid)DeletedAt(DateTime?) β columndeleted_at(timestamp with time zone)RestoredById(Guid?) β columnrestored_by(uuid)RestoredAt(DateTime?) β columnrestored_at(timestamp with time zone)
- Methods
ValidateNotDeleted()β validates that it is not deleted and adds a notificationEnsureNotDeleted()β throws an exception if it is deletedSetUpdatedBy(UpdatedBy updatedById)β updates and increments the versionSetDeleted(DeletedBy deletedById)β marks as deleted, records the user and date of the deletion, updatesUpdatedById/UpdatedAtand increments the versionSetRestored(RestoredBy restoredById)β restores, records the user and date of the restoration, updatesUpdatedById/UpdatedAtand increments the version
- Notes
- Inherits from
DetailedEntity. - On invalid data, throws
BadRequestException. - Usage Examples.
- Inherits from
FileEntity
- Properties
FileName(string) β columnfile_name(text)Title(string) β columntitle(varchar(255))Link(string) β columnlink(text)FileFormat(string?) β columnfile_format(varchar(10))Type(EFileType) β columntype(int)Size(long) β columnsize(bigint)
- Constructors (for derived classes)
FileEntity(FileStorage file, Title title, CreatedBy createdById)FileEntity(FileStorage file, Title title, string fileFormat, EFileType type, long size, CreatedBy createdById)
- Notes
- Inherits from
InitialEntity. FileStorageandTitleare Value Objects. On invalid data, throwsBadRequestException.- Usage Examples.
- Inherits from
π Usage Examples
Base Entity
using Tooark.Entities;
public class Product : BaseEntity
{
public Product() { }
public Product(Guid id) : base(id) { }
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
}
public class Program
{
public static void Main()
{
var product = new Product
{
Name = "Product A",
Price = 100.0m
};
var generatedId = product.Id;
var deterministicProduct = new Product(Guid.Parse("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"));
}
}
Initial Entity
using Tooark.Entities;
public class Product : InitialEntity
{
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
}
public class Program
{
public static void Main()
{
var product = new Product
{
Name = "Product A",
Price = 100.0m
};
// SetCreatedBy receives CreatedBy (Value Object), but Guid converts implicitly.
product.SetCreatedBy(Guid.NewGuid());
}
}
Detailed Entity
using Tooark.Entities;
public class Product : DetailedEntity
{
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
}
public class Program
{
public static void Main()
{
var product = new Product
{
Name = "Product A",
Price = 100.0m
};
product.SetCreatedBy(Guid.NewGuid());
product.SetUpdatedBy(Guid.NewGuid());
}
}
Versioned Entity
using Tooark.Entities;
public class Product : VersionedEntity
{
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
}
public class Program
{
public static void Main()
{
var product = new Product
{
Name = "Product A",
Price = 100.0m
};
product.SetCreatedBy(Guid.NewGuid());
product.SetUpdatedBy(Guid.NewGuid());
var version = product.Version;
}
}
Soft Deletable Entity
using Tooark.Entities;
public class Product : SoftDeletableEntity
{
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
}
public class Program
{
public static void Main()
{
var product = new Product
{
Name = "Product A",
Price = 100.0m
};
product.SetCreatedBy(Guid.NewGuid());
product.SetDeleted(Guid.NewGuid());
product.SetRestored(Guid.NewGuid());
}
}
Auditable Entity
using Tooark.Entities;
public class Product : AuditableEntity
{
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
}
public class Program
{
public static void Main()
{
var product = new Product
{
Name = "Product A",
Price = 100.0m
};
product.SetCreatedBy(Guid.NewGuid());
product.SetUpdatedBy(Guid.NewGuid());
product.SetDeleted(Guid.NewGuid());
product.SetRestored(Guid.NewGuid());
}
}
File Entity
using Tooark.Entities;
using Tooark.Enums;
using Tooark.ValueObjects;
public class Attachment : FileEntity
{
public Attachment(string link, string name, string title, Guid createdById)
: base(new FileStorage(link, name), new Title(title), new CreatedBy(createdById))
{ }
public Attachment(string link, string name, string title, string fileFormat, EFileType type, long size, Guid createdById)
: base(new FileStorage(link, name), new Title(title), fileFormat, type, size, createdById)
{ }
}
public class Program
{
public static void Main()
{
var attachment = new Attachment(
link: "https://bucket.com/file.pdf",
name: "File.pdf",
title: "Test file",
createdById: Guid.NewGuid()
);
var detailedAttachment = new Attachment(
link: "https://bucket.com/file.pdf",
name: "File.pdf",
title: "Test file",
fileFormat: "pdf",
type: EFileType.Document,
size: 1024,
createdById: Guid.NewGuid()
);
}
}
π Dependencies
| Package | Version | Description |
|---|---|---|
Tooark.Enums |
4.x | Shared types, such as EFileType |
Tooark.Exceptions |
4.x | BadRequestException, thrown by the write operations |
Tooark.Notifications |
4.x | Notification base of the entities |
Tooark.Validations |
4.x | Rules used in the FileEntity validation |
Tooark.ValueObjects |
4.x | Value objects received by the constructors and methods |
β οΈ Error Codes, Notifications and Solutions
Notification error codes follow the T.ENT.<ABBR><N> pattern (e.g. T.ENT.BAS1).
Codes emitted by the entities:
| Code | Emitter | Situation |
|---|---|---|
T.ENT.BAS1 |
BaseEntity.SetId |
Empty identifier |
T.ENT.BAS2 |
BaseEntity.SetId |
Attempt to change the identifier |
T.ENT.INI1 |
InitialEntity.SetCreatedBy |
Creation authorship already recorded |
T.ENT.SOF1 |
SoftDeletableEntity.ValidateNotDeleted |
Record soft deleted |
T.ENT.AUD1 |
AuditableEntity.ValidateNotDeleted |
Record soft deleted |
The code travels with the notification, whether it is recorded on the entity or carried by the exception.
Messages coming from the value objects β Field.Invalid;CreatedBy and the others β are emitted by
Tooark.ValueObjects and carry its code, not a T.ENT.* one. Note that a rejected FileEntity link
reports ProtocolHttp, which is the internal value object of FileStorage, not FileStorage.
Error/notification table:
| Entity | Message | Description | Solution | Returns |
|---|---|---|---|---|
BaseEntity |
Field.Empty;Id |
Empty identifier | Set a valid identifier for the entity | Notification |
BaseEntity |
Field.ChangeBlocked;Id |
Identifier cannot be changed | Do not change the identifier of an already created entity | Notification |
InitialEntity |
Field.ChangeBlocked;CreatedBy |
Creator already recorded | Creation authorship is set once; do not redefine it | Exception |
InitialEntity |
Field.Invalid;CreatedBy |
Invalid Creator field | Provide a valid creator | Exception |
DetailedEntity |
Field.ChangeBlocked;CreatedBy |
Creator already recorded | Creation authorship is set once; do not redefine it | Exception |
DetailedEntity |
Field.Invalid;CreatedBy |
Invalid Creator field | Provide a valid creator | Exception |
DetailedEntity |
Field.Invalid;UpdatedBy |
Invalid Updater field | Provide a valid updater | Exception |
VersionedEntity |
Field.ChangeBlocked;CreatedBy |
Creator already recorded | Creation authorship is set once; do not redefine it | Exception |
VersionedEntity |
Field.Invalid;CreatedBy |
Invalid Creator field | Provide a valid creator | Exception |
VersionedEntity |
Field.Invalid;UpdatedBy |
Invalid Updater field | Provide a valid updater | Exception |
SoftDeletableEntity |
Field.ChangeBlocked;CreatedBy |
Creator already recorded | Creation authorship is set once; do not redefine it | Exception |
SoftDeletableEntity |
Field.Invalid;CreatedBy |
Invalid Creator field | Provide a valid creator | Exception |
SoftDeletableEntity |
Field.Invalid;UpdatedBy |
Invalid Updater field | Provide a valid updater | Exception |
SoftDeletableEntity |
Record.Deleted |
Record deleted | Consider whether the record must be restored before operating on it | Notification |
SoftDeletableEntity |
Record.Deleted |
Record deleted | Restore the record if needed before operating on it | Exception |
AuditableEntity |
Field.ChangeBlocked;CreatedBy |
Creator already recorded | Creation authorship is set once; do not redefine it | Exception |
AuditableEntity |
Field.Invalid;CreatedBy |
Invalid Creator field | Provide a valid creator | Exception |
AuditableEntity |
Field.Invalid;UpdatedBy |
Invalid Updater field | Provide a valid updater | Exception |
AuditableEntity |
Field.Invalid;DeletedBy |
Invalid Deleter field | Provide a valid deleter | Exception |
AuditableEntity |
Field.Invalid;RestoredBy |
Invalid Restorer field | Provide a valid restorer | Exception |
AuditableEntity |
Record.Deleted |
Record deleted | Consider whether the record must be restored before operating on it | Notification |
AuditableEntity |
Record.Deleted |
Record deleted | Restore the record if needed before operating on it | Exception |
FileEntity |
Field.Invalid;ProtocolHttp |
Invalid file link | Provide a valid HTTP or HTTPS link | Exception |
FileEntity |
Field.Invalid;Title |
Invalid file title | Provide a valid title | Exception |
FileEntity |
Field.Required;FileStorage |
File not provided | Provide the file's FileStorage |
Exception |
FileEntity |
Field.Required;Title |
Title not provided | Provide the file's Title |
Exception |
FileEntity |
Field.Required;FileFormat |
File format not provided | Provide the file format | Exception |
FileEntity |
Field.Invalid;Size |
Negative file size | Provide a size greater than or equal to zero | Exception |
Applies to every entity: a null argument produces Field.Required;<field> β CreatedBy, UpdatedBy,
DeletedBy or RestoredBy, depending on the operation β as an Exception.
π€ Contributing
Contributions are welcome! Start with CONTRIBUTING.md β it covers the development workflow, the coding and commit conventions and the pull request checklist. Bugs and feature requests go through the issue templates of the Tooark repository.
By participating you agree to the Code of Conduct.
π Help & Security
- β Questions, bugs, feature ideas β see SUPPORT.md for the right channel
- π Security vulnerabilities β do not open a public issue; follow SECURITY.md
π Support
If Tooark helps your projects, consider supporting its development:
- π GitHub Sponsors
- β Ko-fi
Every contribution helps keep the project maintained and improving. Thank you! π
π License
This project is licensed under the BSD 3-Clause License.
| 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 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.AspNetCore.Http (>= 2.3.13)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.12)
- Microsoft.Extensions.Localization (>= 10.0.12)
- Microsoft.Extensions.Options (>= 10.0.12)
- Tooark.Enums (>= 4.7.0)
- Tooark.Exceptions (>= 4.7.0)
- Tooark.Notifications (>= 4.7.0)
- Tooark.Validations (>= 4.7.0)
- Tooark.ValueObjects (>= 4.7.0)
-
net8.0
- Microsoft.AspNetCore.Http (>= 2.3.13)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Localization (>= 8.0.31)
- Microsoft.Extensions.Options (>= 8.0.2)
- Tooark.Enums (>= 4.7.0)
- Tooark.Exceptions (>= 4.7.0)
- Tooark.Notifications (>= 4.7.0)
- Tooark.Validations (>= 4.7.0)
- Tooark.ValueObjects (>= 4.7.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Tooark.Entities:
| Package | Downloads |
|---|---|
|
Tooark
Package with all Tooark resources for .NET applications. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.7.1 | 34 | 10/17/2026 |
| 4.7.0 | 286 | 9/30/2026 |
| 4.6.0 | 159 | 9/29/2026 |
| 4.5.0 | 112 | 9/29/2026 |
| 4.4.0 | 108 | 9/28/2026 |
| 4.3.0 | 117 | 9/26/2026 |
| 4.2.1 | 120 | 9/25/2026 |
| 4.2.0 | 132 | 9/20/2026 |
| 4.1.0 | 118 | 9/18/2026 |
| 4.0.1 | 169 | 8/25/2026 |
| 4.0.0 | 127 | 8/25/2026 |
| 3.3.6 | 102 | 9/18/2026 |
| 3.3.5 | 122 | 8/25/2026 |
| 3.3.4 | 308 | 8/12/2026 |
| 3.3.3 | 380 | 7/27/2026 |
| 3.3.2 | 312 | 6/11/2026 |
| 3.3.1 | 153 | 6/6/2026 |
| 2.3.5 | 101 | 9/18/2026 |
| 2.3.4 | 117 | 8/25/2026 |
| 2.3.3 | 120 | 7/27/2026 |