Xfty.VectorDatabases
1.0.0-beta.1
See the version list below for details.
dotnet add package Xfty.VectorDatabases --version 1.0.0-beta.1
NuGet\Install-Package Xfty.VectorDatabases -Version 1.0.0-beta.1
<PackageReference Include="Xfty.VectorDatabases" Version="1.0.0-beta.1" />
<PackageVersion Include="Xfty.VectorDatabases" Version="1.0.0-beta.1" />
<PackageReference Include="Xfty.VectorDatabases" />
paket add Xfty.VectorDatabases --version 1.0.0-beta.1
#r "nuget: Xfty.VectorDatabases, 1.0.0-beta.1"
#:package Xfty.VectorDatabases@1.0.0-beta.1
#addin nuget:?package=Xfty.VectorDatabases&version=1.0.0-beta.1&prerelease
#tool nuget:?package=Xfty.VectorDatabases&version=1.0.0-beta.1&prerelease
XFTY — Extreme C# Test Data Factory
XFTY is a declarative test data factory for C#.
Instead of manually constructing complete object graphs for every test, you
describe only the values your test actually cares about. XFTY supplies
sensible defaults, automatically creates related records, and either mocks
persistence entirely or actually inserts through a pluggable
IPersistenceGateway — the same Provider definitions serve a pure in-memory
unit test and a real database integration test.
By centralizing test data definitions, XFTY dramatically reduces boilerplate and makes tests more resilient to changing validation rules, required fields, and evolving business logic.
Why XFTY?
As a project grows, so does the amount of code required simply to create valid test data.
A Contact requires an Account. Later, a validation rule requires
additional Account fields. Eventually another related type becomes
mandatory. Over time, hundreds or even thousands of tests can end up
duplicating nearly identical setup code.
XFTY centralizes that knowledge.
Instead of every test knowing how to construct a valid object graph, Providers define that logic once, allowing individual tests to override only the fields they actually care about.
The result is test code that is:
- shorter
- easier to read
- easier to maintain
- more resilient to application changes
Features
- Declarative test data generation, described once per Provider
- Automatic relationship generation — required, optional, shared ancestors, self-referential cycles guarded automatically
- Context-aware values: a field derived from a sibling, a generated
ancestor, or (once the graph exists) a generated child, with a loud error
on a mis-ordered read instead of a silent wrong
null - Per-call relationship control (
IncludeOptional,ExcludeRelationship) without touching a Provider's own definition - Real persistence through
IPersistenceGateway—Xfty.EntityFrameworkCoreships an EF Core implementation, proven against SQLite and a real Postgres container — or mock Ids with no database touched at all - Optional add-on packages for common conveniences core
Xftydoesn't bundle:Xfty.Bogus(realistic names/emails/addresses/paragraphs),Xfty.VectorDatabases(a random-vector value expression for an embedding field),Xfty.AutoFixture, andXfty.AutoBogus(both: pointCreate<T>()/Generate<T>()at aRecordProvider, and/or let the tool fill fields no Provider declares) — none is a dependency of coreXftyitself - Deferred and depth-batched insert: build a graph across several calls, then insert it once, in dependency order, across mixed record types
- Multi-variant Providers (
FlavouredLookupKey,DiscriminatorLookupKey) — resolve a different Provider for the same type by an arbitrary predicate or field value - Lambda-based field access throughout (
x => x.Field, not a barePropertyInfoornameof(...)) - Extensible Provider architecture — implement
IRecordProviderdirectly, or useSimpleRecordProvider<T>when a Provider is nothing but a template - Suitable for both isolated unit tests and real-database integration tests, with the same Provider definitions
See How XFTY compares for how this stacks up against AutoFixture, Bogus, and similar libraries.
Quick Example
Generate a Contact with sensible defaults:
DefaultProviderLookup lookup = new();
Contact contact = (Contact)new RecordProvider(typeof(Contact), lookup)
.Supply();
Override only the fields your test actually cares about:
Contact contact = (Contact)new RecordProvider(typeof(Contact), lookup)
.Put<Contact>(x => x.FirstName, "Alice")
.SetInsertMode(InsertMode.Mock)
.Supply();
Generate complete related object graphs:
Bundle bundle = new RecordProvider(typeof(Contact), lookup)
.SetInsertMode(InsertMode.Mock)
.SetInclusivity(InsertInclusivity.All)
.SupplyBundle();
Contact contact = (Contact)bundle.GetList<Contact>(x => x.Id)![0];
Account account = (Account)bundle.GetList<Contact>(x => x.AccountId)![0];
Assert.Equal(account.Id, contact.AccountId);
Documentation
Full documentation is in docs/, organised by audience:
| I want to… | Go to |
|---|---|
| Use XFTY to write tests | docs/use/ — start with getting-started |
| Teach XFTY about my own record types | docs/extend/ |
| Work on XFTY itself | docs/contribute/ — architecture |
| Look something up | docs/reference/ — api-cheatsheet, known-issues |
| See what's built / planned | docs/roadmap/ |
Design Philosophy
XFTY was designed around a simple idea:
Tests should describe only what makes them unique.
Everything else should be generated automatically.
Rather than scattering test data throughout an entire codebase, XFTY moves that knowledge into reusable Providers that declaratively describe valid records and their relationships.
The framework then constructs those object graphs automatically, allowing test code to remain focused on the behaviour being tested rather than on setup.
How XFTY Compares
XFTY is not a general-purpose "fill in an object" library like AutoFixture, and it doesn't ship realistic fake-data generators like Bogus. What it does that they don't:
- Generates a related graph — required/optional relationships, shared ancestors deduplicated across many children, self-referential cycles guarded automatically — not one object at a time.
- Has an actual opinion about persistence: the same Provider definitions
run as a pure in-memory
Mockin a unit test, or insert for real throughIPersistenceGatewayin an integration test, with no rewrite. - Resolves a different Provider variant for the same type by a runtime key or predicate, and supports context-aware values — a field derived from a sibling, ancestor, or generated child, with a loud guard against reading one that hasn't been generated yet.
Core Xfty has no built-in realistic fake-data generation (Xfty.Bogus is
an optional add-on for that) and no auto-population by default - every
field a Provider cares about is declared, not guessed. Xfty.AutoFixture
and Xfty.AutoBogus are optional pairings for the fields a Provider
doesn't care about (or for pointing the tool's own generation at a
Provider directly) - neither changes core Xfty's own philosophy. See
docs/reference/comparison.md for the full,
unvarnished comparison against AutoFixture, Bogus, AutoBogus, and NBuilder,
including where XFTY is a worse fit than any of them.
Roadmap
Recently landed (see the CHANGELOG for the full detail, including everything since the 1.0.0-beta.1 tag):
- Real persistence via
IPersistenceGateway(Xfty.EntityFrameworkCore, proven against SQLite and a real Postgres container) DiscriminatorLookupKey— resolving a Provider by a field's value- Lambda-based field access across the whole public API
- A full sweep to a from-scratch, idiomatic C# port with no remaining Salesforce-specific surface
Xfty.BogusandXfty.VectorDatabases— optional packages for realistic fake data and vector-embedding fields, without adding either dependency to coreXftyXfty.Xunit—[IsolatesSharedAncestor], resettingSharedAncestorbefore/after a test class or method automatically- A real, fixed thread-safety issue in
SharedAncestorunder concurrent test execution (xUnit's default; this repo's own suite had opted out) - Typed
RecordProvider<TRecord>/ChildProvider<TChild>wrappers — no cast at theSupply()call site, plus aMasterTemplate<TRecord>-style object-initializer indexer Xfty.AutoFixture— pairs XFTY with AutoFixture both directions: pointfixture.Create<T>()at a registeredRecordProvider, and/or let AutoFixture fill in whatever fields a Provider's Master Template left unsetXfty.AutoBogus— the same pairing for AutoBogus (AutoFixture-style auto-population plus Bogus's realistic generators), completing the trifecta: XFTY now pairs with AutoFixture, Bogus, and AutoBogus
The full status table — built, not-ported, and open ideas under consideration (embedded/denormalized document relationships) — is docs/roadmap/README.md.
Contributing
Contributions, bug reports, feature requests, and discussions are welcome.
If you would like to contribute:
- Open an issue to discuss proposed changes.
- Keep Provider implementations declarative whenever possible.
- Preserve backwards compatibility unless a compelling reason exists not to.
- Prefer simplicity and readability over additional abstraction.
License
This project is released under the MIT License.
| 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
- Xfty (>= 1.0.0-beta.1)
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.0-beta.12 | 48 | 9/18/2026 |
| 1.0.0-beta.11 | 58 | 9/10/2026 |
| 1.0.0-beta.10 | 50 | 9/10/2026 |
| 1.0.0-beta.9 | 53 | 9/10/2026 |
| 1.0.0-beta.8 | 69 | 9/10/2026 |
| 1.0.0-beta.7 | 56 | 9/7/2026 |
| 1.0.0-beta.6 | 56 | 9/7/2026 |
| 1.0.0-beta.5 | 69 | 9/6/2026 |
| 1.0.0-beta.3 | 71 | 9/6/2026 |
| 1.0.0-beta.2 | 64 | 9/6/2026 |
| 1.0.0-beta.1 | 68 | 9/6/2026 |