Franz.Common.Business
1.4.4
See the version list below for details.
dotnet add package Franz.Common.Business --version 1.4.4
NuGet\Install-Package Franz.Common.Business -Version 1.4.4
<PackageReference Include="Franz.Common.Business" Version="1.4.4" />
<PackageVersion Include="Franz.Common.Business" Version="1.4.4" />
<PackageReference Include="Franz.Common.Business" />
paket add Franz.Common.Business --version 1.4.4
#r "nuget: Franz.Common.Business, 1.4.4"
#:package Franz.Common.Business@1.4.4
#addin nuget:?package=Franz.Common.Business&version=1.4.4
#tool nuget:?package=Franz.Common.Business&version=1.4.4
Franz.Common.Business
A core library of the Franz Framework, designed to facilitate Domain-Driven Design (DDD) and CQRS (Command Query Responsibility Segregation) in .NET applications. It provides abstractions, utilities, and patterns for building scalable, maintainable, and testable business logic.
- Current Version: 1.4.3
Features
1. Domain-Driven Design (DDD) Building Blocks
- Entities: Represent unique objects identified by a primary key, with auditing + soft delete built-in.
- Value Objects: Immutable, equality-driven domain concepts.
- Enumerations: Strongly typed enums with behavior and metadata.
- Repositories: Interfaces for persistence (
IAggregateRepository<TAggregateRoot>
,IReadRepository<T>
).
Entity Example:
public class Order : Entity<Guid>
{
public string CustomerName { get; private set; }
public decimal TotalAmount { get; private set; }
public Order(Guid orderId, string customerName, decimal totalAmount)
{
Id = orderId;
CustomerName = customerName;
TotalAmount = totalAmount;
}
}
Value Object Example:
public class Address : ValueObject
{
public string Street { get; }
public string City { get; }
public string PostalCode { get; }
public Address(string street, string city, string postalCode)
{
Street = street;
City = city;
PostalCode = postalCode;
}
protected override IEnumerable<object> GetEqualityComponents()
{
yield return Street;
yield return City;
yield return PostalCode;
}
}
2. Aggregates (Event-Sourced)
π Since 1.2.65, aggregates follow a strict event-driven model:
- Enforce consistency across related entities.
- State is modified only through events.
- Support replay via event sourcing.
- Always identified by
Guid
.
Example:
public class Product : EventSourcedAggregateRoot<ProductEvent>
{
public string Name { get; private set; }
public decimal Price { get; private set; }
private readonly List<ProductReview> _reviews = new();
public IReadOnlyCollection<ProductReview> Reviews => _reviews.AsReadOnly();
public Product(Guid id, string name, decimal price) : base(id)
{
RaiseEvent(new ProductCreatedEvent(id, name, price));
}
public void UpdatePrice(decimal newPrice)
{
if (newPrice <= 0) throw new InvalidOperationException("Price must be positive.");
RaiseEvent(new ProductPriceUpdatedEvent(Id, newPrice));
}
public void AddReview(string comment, int rating)
{
if (rating < 1 || rating > 5) throw new InvalidOperationException("Rating must be between 1 and 5.");
RaiseEvent(new ProductReviewAddedEvent(Id, comment, rating));
}
public void Apply(ProductCreatedEvent @event) { Id = @event.ProductId; Name = @event.Name; Price = @event.Price; }
public void Apply(ProductPriceUpdatedEvent @event) { Price = @event.NewPrice; }
public void Apply(ProductReviewAddedEvent @event) { _reviews.Add(new ProductReview(@event.Comment, @event.Rating)); }
}
3. Events
Supports both domain events and integration events.
IEvent
IEventHandler<TEvent>
IntegrationEvent
BaseEvent
Example:
public class OrderCreatedEvent : IEvent
{
public Guid OrderId { get; set; }
public string CustomerName { get; set; }
}
public class OrderCreatedHandler : IEventHandler<OrderCreatedEvent>
{
public async Task Handle(OrderCreatedEvent @event, CancellationToken cancellationToken)
{
Console.WriteLine($"Order created for {@event.CustomerName}.");
}
}
4. CQRS Support
- Commands (
ICommandRequest<T>
,ICommandHandler<TCommand,TResponse>
) - Queries (
IQueryRequest<T>
,IQueryHandler<TQuery,TResponse>
)
Command Example:
public class CreateOrderCommand : ICommandRequest<Guid>
{
public string CustomerName { get; set; }
public decimal TotalAmount { get; set; }
}
public class CreateOrderHandler : ICommandHandler<CreateOrderCommand, Guid>
{
public async Task<Guid> Handle(CreateOrderCommand request, CancellationToken cancellationToken)
{
var orderId = Guid.NewGuid();
Console.WriteLine($"Order created for {request.CustomerName} with ID: {orderId}");
return orderId;
}
}
5. Registration Examples
The Business layer integrates seamlessly with the Mediator and resilience pipelines.
a) AddBusinessWithMediator
Strict registration β will throw if your *.Application
assembly is not found.
builder.Services.AddBusinessWithMediator(typeof(Program).Assembly);
b) TryAddBusinessWithMediator
Soft registration β logs a warning but continues if the application assembly is missing.
builder.Services.TryAddBusinessWithMediator(typeof(Program).Assembly);
c) AddFranzPlatform
Full-stack registration β Business + Mediator + Logging + Resilience pipelines.
builder.Services.AddFranzPlatform(
typeof(Program).Assembly,
options =>
{
options.DefaultTimeout = TimeSpan.FromSeconds(30);
});
6. Resilience Pipelines (via Mediator)
When you call AddFranzPlatform
, Franz.Common.Business
wires up the following Mediator pipelines:
- β
RetryPipeline<TRequest, TResponse>
- β
CircuitBreakerPipeline<TRequest, TResponse>
- β
TimeoutPipeline<TRequest, TResponse>
- β
BulkheadPipeline<TRequest, TResponse>
These are implemented in
Franz.Common.Mediator.Pipelines.Resilience
.Franz.Common.Business
just activates them for you.
7. appsettings.json Configuration
Each pipeline reads its Options from configuration:
{
"Franz": {
"Resilience": {
"Retry": {
"Enabled": true,
"RetryCount": 3,
"BaseDelayMilliseconds": 200
},
"CircuitBreaker": {
"Enabled": true,
"FailureThreshold": 5,
"OpenDurationSeconds": 60
},
"Timeout": {
"Enabled": true,
"TimeoutSeconds": 15
},
"Bulkhead": {
"Enabled": true,
"MaxParallelization": 50,
"MaxQueuingActions": 100
}
}
}
}
8. Options Mapping
Retry
βRetryOptions
CircuitBreaker
βCircuitBreakerOptions
Timeout
βTimeoutOptions
Bulkhead
βBulkheadOptions
9. Logging
On startup youβll see log messages confirming bootstrap:
[INF] β
Franz.Business bootstrapped with MyProduct.Application, Version=1.0.0.0
[INF] π‘οΈ Resilience pipelines registered: Retry, CircuitBreaker, Timeout, Bulkhead
[WRN] β οΈ No Application assembly found for MyProduct.Application, Business layer not registered.
Whatβs New in 1.4.2
- ποΈ Removed
SaveEntitiesAsync
β all auditing + domain event dispatching happens inSaveChangesAsync
. - β
Aligned with DbContextBase from
Franz.Common.EntityFramework
. - π§Ή Internal cleanup and consistency improvements.
Dependencies
- Scrutor (4.2.2) β assembly scanning & DI.
- Microsoft.Extensions.DependencyInjection (9.0.0) β DI support.
- Franz.Common.Mediator β CQRS + pipelines.
- Franz.Common.Errors β standardized error handling.
Installation
dotnet add package Franz.Common.Business --version 1.4.2
β οΈ Since 1.4.1, MediatR is no longer required. Uses Franz.Common.Mediator internally.
Contributing
This package is part of the private Franz Framework.
- Clone repo.
- Create a feature branch.
- Submit a PR for review.
License
Licensed under the MIT License.
Changelog
1.4.2
- Removed
SaveEntitiesAsync
β replaced withSaveChangesAsync
inDbContextBase
. - Improved alignment with
EntityFramework
package (auditing + domain events).
1.4.1
- Independent from MediatR β runs on
Franz.Common.Mediator
. - Lifecycle tracking for entities & aggregates.
- Stronger value object equality.
- Enriched domain events with metadata.
- Scrutor-powered DI auto-discovery.
1.3
- Upgraded to .NET 9.
- Compatible with both in-house mediator & MediatR.
1.2.65
- Aggregates redesigned to use event sourcing.
- All aggregates now require
Guid
identifiers.
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
- Franz.Common.DependencyInjection (>= 1.4.4)
- Franz.Common.Errors (>= 1.4.4)
- Franz.Common.Mediator (>= 1.4.4)
- Microsoft.CSharp (>= 4.7.0)
- Microsoft.Extensions.DependencyInjection (>= 9.0.8)
- Scrutor (>= 6.1.0)
NuGet packages (6)
Showing the top 5 NuGet packages that depend on Franz.Common.Business:
Package | Downloads |
---|---|
Franz.Common.EntityFramework
Shared utility library for the Franz Framework. |
|
Franz.Common.Messaging
Shared utility library for the Franz Framework. |
|
Franz.Common.Serialization
Shared utility library for the Franz Framework. |
|
Franz.Common.Bootstrap
Shared utility library for the Franz Framework. |
|
Franz.Common.Http.Documentation
Shared utility library for the Franz Framework. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
1.5.3 | 16 | 9/21/2025 |
1.5.2 | 21 | 9/21/2025 |
1.5.0 | 26 | 9/21/2025 |
1.4.4 | 75 | 9/20/2025 |
1.3.14 | 244 | 9/18/2025 |
1.3.13 | 235 | 9/18/2025 |
1.3.5 | 267 | 9/17/2025 |
1.3.4 | 297 | 9/16/2025 |
1.3.3 | 305 | 9/16/2025 |
1.3.2 | 304 | 9/15/2025 |
1.3.1 | 124 | 9/12/2025 |
1.3.0 | 329 | 8/25/2025 |
1.2.65 | 280 | 3/3/2025 |
1.2.64 | 221 | 1/29/2025 |
1.2.63 | 263 | 1/27/2025 |
1.2.62 | 272 | 1/8/2025 |