Franz.Common.Business
2.3.3
dotnet add package Franz.Common.Business --version 2.3.3
NuGet\Install-Package Franz.Common.Business -Version 2.3.3
<PackageReference Include="Franz.Common.Business" Version="2.3.3" />
<PackageVersion Include="Franz.Common.Business" Version="2.3.3" />
<PackageReference Include="Franz.Common.Business" />
paket add Franz.Common.Business --version 2.3.3
#r "nuget: Franz.Common.Business, 2.3.3"
#:package Franz.Common.Business@2.3.3
#addin nuget:?package=Franz.Common.Business&version=2.3.3
#tool nuget:?package=Franz.Common.Business&version=2.3.3
Franz.Common.Business
Domain and application building blocks for the Franz.Common framework on .NET 10.
Overview
The Franz.Common.Business package provides the domain and application building blocks capability within Franz.Common. It is designed to be composed with the rest of the framework rather than imposing unrelated infrastructure choices on every application.
Installation
dotnet add package Franz.Common.Business
Design principles
- Explicit composition: register only the capabilities the application needs.
- Clear boundaries: keep domain and application contracts independent from provider-specific infrastructure where the package's role permits it.
- Predictable behavior: make configuration, failure modes, and lifecycle ownership visible rather than relying on hidden conventions.
- Operational readiness: validate security, resilience, diagnostics, and compatibility for the actual deployment environment.
Usage and configuration
Follow the package-specific setup, configuration, and code examples below. Only configure external services when this package requires them, and keep secrets outside source control.
Package-specific guide
A core infrastructure library of the Franz Framework, designed to support Domain-Driven Design (DDD), CQRS, and Event-Sourcing-ready architectures in modern .NET applications.
It provides a clean, deterministic, and production-grade foundation for building scalable business systems with strong separation of concerns.
๐ Version
Current Version: v2.3.3
๐ง Core Philosophy
Franz.Common.Business enforces the following principles:
- Identity is factory-controlled
- Domain logic is persistence-agnostic
- Repositories are storage-only abstractions
- Entities are immutable in identity after creation
- DI is deterministic and explicit
- No hidden service locator or runtime DI construction
โจ Key Features
1. Domain Model (DDD Core)
โ Entity Model
All domain entities derive from a unified base:
public abstract class Entity<TId> : IEntity
{
public TId Id { get; private set; } = default!;
protected Entity() { }
protected Entity(TId id)
{
Id = id;
}
public object GetId() => Id!;
}
โ Key characteristics:
- Strongly typed identity (
Guidorint) - Factory-controlled identity assignment
- Immutable identity after creation
- Equality based on identity
- EF Core compatible design
2. Identity System
โ Supported ID strategies
Guid V7(default standard)int(database-generated identities)
โ Centralized ID generation
public interface IIdGenerator<TId>
{
TId Create();
}
โ Default implementation:
public sealed class GuidV7Generator : IIdGenerator<Guid>
{
public Guid Create() => Guid.CreateVersion7();
}
3. Entity Factories
Entities must be created through controlled factories.
public interface IEntityFactory<TId, TEntity>
where TEntity : Entity<TId>
{
TEntity Create();
}
โ Responsibilities:
- Generate entity identity via
IIdGenerator<TId> - Ensure consistent creation rules
- Enforce domain construction invariants
- Prevent identity bypass (e.g.
new Entity()misuse)
โ Implementation: EntityFactory<TKey, TEntity>
The default implementation uses a compiled expression tree delegate, cached statically per closed generic type, to invoke the entity's protected constructor with zero reflection overhead after startup.
public sealed class EntityFactory<TKey, TEntity> : IEntityFactory<TKey, TEntity>
where TEntity : Entity<TKey>
{
public TEntity Create() => _activator(_idGenerator.Create());
}
How it works
| Concern | Mechanism |
|---|---|
| Constructor discovery | BindingFlags.NonPublic \| Public โ resolves protected constructors |
| Delegate compilation | Expression.Lambda<Func<TKey, TEntity>>(...).Compile() |
| Caching | Static field โ compiled once per TEntity type, shared for the application lifetime |
| Null guard | ArgumentNullException.ThrowIfNull on the injected IIdGenerator<TKey> |
| Misconfiguration | Throws TypeInitializationException with an actionable inner message if the required constructor is absent |
| Eager validation | EntityFactory<TKey, TEntity>.Validate() triggers the static constructor at DI registration time |
Required entity constructor
Every entity must expose a constructor accepting its key type:
public class Order : Entity<Guid>
{
protected Order(Guid id) : base(id) { }
}
Eager validation at startup
Call Validate() from your DI registration extension to surface misconfigured entity types immediately, rather than on first use:
services.AddSingleton<IEntityFactory<Guid, Order>, EntityFactory<Guid, Order>>();
EntityFactory<Guid, Order>.Validate();
4. Aggregate Factories
Aggregate roots follow the same factory pattern via AggregateFactory<TAggregate, TEvent>.
public interface IAggregateFactory<TAggregate>
{
TAggregate Create();
}
โ Implementation: AggregateFactory<TAggregate, TEvent>
Mirrors EntityFactory exactly โ compiled delegate, static cache, fail-fast error messages, and eager validation support โ but is scoped to AggregateRoot<TEvent> and hardcoded to Guid identity, consistent with the event-sourcing model.
public sealed class AggregateFactory<TAggregate, TEvent> : IAggregateFactory<TAggregate>
where TAggregate : AggregateRoot<TEvent>
where TEvent : IEvent
{
public TAggregate Create() => _activator(_idGenerator.Create());
}
Required aggregate constructor
public class OrderAggregate : AggregateRoot<OrderEvent>
{
protected OrderAggregate(Guid id) : base(id) { }
}
Eager validation at startup
services.AddSingleton<IAggregateFactory<OrderAggregate>, AggregateFactory<OrderAggregate, OrderEvent>>();
AggregateFactory<OrderAggregate, OrderEvent>.Validate();
5. Repositories (Persistence Layer)
Repositories are identity-agnostic and persistence-only abstractions.
public interface IEntityRepository<TEntity>
where TEntity : class, IEntity
{
Task<TEntity> GetByIdAsync(object id, CancellationToken cancellationToken = default);
Task AddAsync(TEntity entity, CancellationToken cancellationToken = default);
Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default);
Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default);
}
โ Design principles:
- No dependency on
TId - No domain logic
- EF Core handles identity resolution
- Supports both
Guidandintprimary keys
6. Aggregates & Event Sourcing
โ Aggregate Root
Supports event-driven state mutation:
public abstract class AggregateRoot<TEvent> : Entity<Guid>
where TEvent : IEvent
{
protected void RaiseEvent(TEvent @event) { }
public void ReplayEvents(IEnumerable<TEvent> events) { }
public void Rehydrate(Guid id, IEnumerable<TEvent> events) { }
}
โ Features:
- Event-based state changes
- Automatic version tracking
- Uncommitted event collection
- Full rehydration support
7. Domain Events
All events implement:
public interface IDomainEvent : IEvent
{
Guid EventId { get; }
DateTimeOffset OccurredOn { get; }
string? CorrelationId { get; }
Guid? AggregateId { get; }
string AggregateType { get; }
string EventType { get; }
}
โ Benefits:
- Full auditability
- Distributed tracing support
- Event correlation across services
8. CQRS Support
Built-in support for:
- Commands (
ICommandHandler) - Queries (
IQueryHandler) - Mediator-based execution pipeline
9. Resilience Pipelines
Production-ready pipeline support:
- Retry
- Circuit Breaker
- Timeout
- Bulkhead Isolation
10. Dependency Injection Bootstrap
โ Single entry point:
services.AddBusiness(applicationAssembly);
services.AddBusinessPlatform();
โ What it registers:
Domain layer
IIdGenerator<Guid>IEntityFactory<,>IAggregateFactory<>
Mediator layer
- Command/query pipeline
- Event dispatching
Handler discovery
- Automatic handler registration
โ ๏ธ Important Design Rules
โ Do NOT:
- Generate IDs manually (
Guid.NewGuid()) - Bypass factories for entity creation
- Define entities without a
protected T(TKey id)constructor - Use service locator inside startup/configuration
- Introduce custom repository identity types
โ Always:
- Use factories for entity creation
- Use
IIdGenerator<TId>for identity - Define the required single-parameter constructor on every entity and aggregate
- Call
Validate()at DI registration time to catch constructor mismatches at startup - Treat repositories as persistence-only abstractions
๐งฉ Architecture Overview
Domain Layer
โโโ Entities (Entity<TId>)
โโโ Aggregates (AggregateRoot<TEvent>)
โโโ Value Objects
โโโ Domain Events
Factory Layer
โโโ IEntityFactory<TId, TEntity> โ EntityFactory<TKey, TEntity>
โโโ IAggregateFactory<TAggregate> โ AggregateFactory<TAggregate, TEvent>
Identity Layer
โโโ IIdGenerator<TId>
Persistence Layer
โโโ IEntityRepository<TEntity>
Application Layer
โโโ CQRS + Mediator
Bootstrap Layer
โโโ AddBusiness()
๐งช Version History
v2.2.09 โ Factory Hardening
- Replaced reflection-on-every-call pattern with compiled expression tree delegates in both
EntityFactoryandAggregateFactory - Delegates are compiled once per closed generic type and cached in a static field for the application lifetime โ near-native instantiation performance
- Removed the injected
Func<Guid, TAggregate> activatorfromAggregateFactoryโ the factory now owns constructor resolution entirely, eliminating a class of registration-site errors - Added
TypeInitializationExceptionwith a descriptive inner message when the required single-parameter constructor is absent, replacing the previous opaque CLR failure - Added
ArgumentNullException.ThrowIfNullguard on injectedIIdGenerator<TKey>instances - Added static
Validate()method to both factories โ call at DI registration time to surface misconfigured types at startup rather than on first use - Removed unused
System.Collections.Concurrent,System.Collections.Generic, andSystem.Textimports from factory files
v2.0.3 โ Architecture Stabilization
- Enforced factory-driven identity model
- Removed mutable identity assignment (
SetIdeliminated) - Introduced immutable entity identity lifecycle
- Simplified repository abstraction (identity-agnostic)
- Consolidated DI bootstrap into single deterministic entry point
- Removed ServiceProvider creation from configuration pipeline
- Improved EF Core compatibility and consistency
- Strengthened DDD alignment across domain layer
๐ Summary
Franz.Common.Business v2.2.13 provides a:
โ deterministic โ factory-driven โ EF Core compatible โ DDD-aligned โ CQRS-ready
foundation for enterprise-grade .NET applications.
๐ง Final Note
This library enforces architectural discipline by design, not convention.
It ensures that:
- identity is always controlled
- domain logic remains pure
- persistence remains isolated
- system composition is deterministic
Dependency maintenance โ October 2026
This project's dependency references were reviewed and updated as part of the repository-wide .NET 10 maintenance pass. The intended target framework and public API remain unchanged. Verify the resolved direct and transitive dependency graph through the repository's dependency validation workflow before publishing. See the central dependency upgrade record.
| 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
- Franz.Common.DependencyInjection (>= 2.3.3)
- Franz.Common.Errors (>= 2.3.3)
- Franz.Common.Mediator (>= 2.3.3)
- Microsoft.Extensions.DependencyInjection (>= 10.0.14)
- Scrutor (>= 7.0.0)
NuGet packages (8)
Showing the top 5 NuGet packages that depend on Franz.Common.Business:
| Package | Downloads |
|---|---|
|
Franz.Common.Serialization
Shared utility library for the Franz Framework. |
|
|
Franz.Common.Messaging
Shared utility library for the Franz Framework. |
|
|
Franz.Common.EntityFramework
Shared utility library for the Franz Framework. |
|
|
Franz.Common.Bootstrap
Shared utility library for the Franz Framework. |
|
|
Franz.Common.MongoDB
Shared utility library for the Franz Framework. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.3.3 | 183 | 10/28/2026 |
| 2.3.2 | 184 | 10/27/2026 |
| 2.3.1 | 369 | 10/26/2026 |
| 2.3.0 | 634 | 7/21/2026 |
| 2.2.19 | 501 | 7/19/2026 |
| 2.2.18 | 490 | 7/19/2026 |
| 2.2.17 | 580 | 7/12/2026 |
| 2.2.16 | 490 | 7/2/2026 |
| 2.2.15 | 492 | 6/29/2026 |
| 2.2.14 | 500 | 6/29/2026 |
| 2.2.13 | 507 | 6/29/2026 |
| 2.2.12 | 489 | 6/28/2026 |
| 2.2.11 | 500 | 6/28/2026 |
| 2.2.10 | 493 | 6/28/2026 |
| 2.2.9 | 499 | 6/28/2026 |
| 2.2.8 | 494 | 6/28/2026 |
| 2.2.7 | 496 | 6/7/2026 |
| 2.2.6 | 498 | 6/6/2026 |
| 2.2.5 | 508 | 6/4/2026 |
| 2.2.4 | 485 | 6/3/2026 |