FractalDataWorks.Services.Abstractions
0.7.0-alpha.1022
dotnet add package FractalDataWorks.Services.Abstractions --version 0.7.0-alpha.1022
NuGet\Install-Package FractalDataWorks.Services.Abstractions -Version 0.7.0-alpha.1022
<PackageReference Include="FractalDataWorks.Services.Abstractions" Version="0.7.0-alpha.1022" />
<PackageVersion Include="FractalDataWorks.Services.Abstractions" Version="0.7.0-alpha.1022" />
<PackageReference Include="FractalDataWorks.Services.Abstractions" />
paket add FractalDataWorks.Services.Abstractions --version 0.7.0-alpha.1022
#r "nuget: FractalDataWorks.Services.Abstractions, 0.7.0-alpha.1022"
#:package FractalDataWorks.Services.Abstractions@0.7.0-alpha.1022
#addin nuget:?package=FractalDataWorks.Services.Abstractions&version=0.7.0-alpha.1022&prerelease
#tool nuget:?package=FractalDataWorks.Services.Abstractions&version=0.7.0-alpha.1022&prerelease
FractalDataWorks.Services.Abstractions
Domain service contracts for the FractalDataWorks service framework. This library defines the foundational abstractions for domain-driven service architectures with command-based operations, type-safe configuration, and integrated messaging.
Table of Contents
- Domain Service Architecture
- Framework Integration
- Component Rules and Placement
- Core Interface Hierarchy
- Command System
- Configuration System
- Factory System
- Provider System
- Message Integration
- Generic Constraints Reference
Domain Service Architecture
What is a Domain Service (Service Type)?
A domain service (or service type) is a logical grouping of related services that handle a specific business area. Unlike individual services, domain services provide:
- Unified abstraction over multiple implementations
- Type-safe service discovery without knowing specific implementations
- Domain-specific command hierarchies that all implementations understand
- Coordinated configuration and messaging across the domain
Domain vs Individual Services
// ❌ Individual Service Approach
IUserRegistrationService registrationService;
IUserAuthenticationService authService;
IUserProfileService profileService;
// ✅ Domain Service Approach
IUserManagementService userService; // Can be ANY implementation:
// - DatabaseUserManagementService
// - LdapUserManagementService
// - AzureAdUserManagementService
// - CompositeUserManagementService
Domain Project Structure
Every domain service requires exactly two projects:
MyCompany.Services.UserManagement.Abstractions/ (netstandard2.0)
MyCompany.Services.UserManagement/ (net10.0+)
Why Two Projects?
Abstractions (netstandard2.0) = Pure Contracts
- Maximum compatibility across .NET implementations
- Zero implementation logic
- Consumer dependencies stay minimal
- Stable API surface
Concrete (target framework) = Domain Foundation
- Base classes for implementations to inherit from
- Source-generated type collections
- Framework-specific optimizations
- Implementation extension points
Domain Service Provider Pattern
The DomainServiceProvider enables the "any implementation" pattern:
public interface IUserManagementServiceProvider : IGenericServiceProvider
{
// Get ANY user management service - don't care which implementation
Task<IGenericResult<IUserManagementService>> GetService();
Task<IGenericResult<IUserManagementService>> GetService(string configurationName);
Task<IGenericResult<TService>> GetService<TService>() where TService : IUserManagementService;
}
Critical Pattern: Services are resolved by domain capability, not specific implementation type.
Framework Integration
Domain services integrate with three core framework systems to create a cohesive development experience:
1. ServiceTypes Collections Project (Source-Generated Discovery)
// Auto-generated from domain implementations in solution
public static class UserManagementServices
{
public static DatabaseUserManagementService Database => new();
public static LdapUserManagementService Ldap => new();
public static AzureAdUserManagementService AzureAd => new();
public static IEnumerable<IUserManagementService> All =>
new IUserManagementService[] { Database, Ldap, AzureAd };
}
How it Works:
- Source generator scans solution for
IUserManagementServiceimplementations - Generates type-safe collections for discovery
- Enables runtime enumeration and selection
- Integrates with DI container registration
2. Messages System (Structured Communication)
// Domain message hierarchy
[MessageCollection("UserManagementMessages")]
public abstract class UserManagementMessage : MessageTemplate<MessageSeverity>, IServiceMessage
{
protected UserManagementMessage(int id, string name, MessageSeverity severity,
string message, string? code = null)
: base(id, name, severity, "UserManagement", message, code, null, null) { }
}
// Source-generated factory methods
public static class UserManagementMessages
{
public static UserCreatedMessage UserCreated(string userId) => new(userId);
public static ValidationFailedMessage ValidationFailed(string field) => new(field);
}
Integration Points:
- Messages integrate with
IGenericResultfor structured error handling - Source-generated factory methods ensure consistent message creation
- Automatic message ID allocation prevents conflicts
- Integrated with logging for structured telemetry
3. Logging System (High-Performance Structured Logging)
// Source-generated logging methods
[ExcludeFromCodeCoverage]
public static partial class UserManagementServiceLog
{
[LoggerMessage(EventId = 1, Level = LogLevel.Information,
Message = "Creating user {UserId} with email {Email}")]
public static partial void UserCreationStarted(ILogger logger, string userId, string email);
[LoggerMessage(EventId = 2, Level = LogLevel.Error,
Message = "User creation failed for {UserId}: {ErrorMessage}")]
public static partial void UserCreationFailed(ILogger logger, string userId, string errorMessage, Exception exception);
}
Integration Benefits:
- Zero-allocation logging with compile-time validation
- Consistent structured data across all domain services
- Automatic event ID management
- Integrated with Messages for correlated telemetry
System Cohesion
The three systems work together to create a unified development experience:
public class UserManagementServiceBase : ServiceBase<UserManagementCommand, UserManagementConfiguration, UserManagementServiceBase>
{
public override async Task<IGenericResult> Execute(UserManagementCommand command)
{
// 1. Logging integration
UserManagementServiceLog.CommandExecutionStarted(Logger, command.GetType().Name);
try
{
// Execute business logic
var result = await ProcessCommand(command);
// 2. Messages integration
var successMessage = UserManagementMessages.CommandExecuted(command.GetType().Name);
UserManagementServiceLog.CommandExecutionCompleted(Logger, command.GetType().Name);
return GenericResult.Success(successMessage);
}
catch (Exception ex)
{
// 3. Coordinated error handling
var errorMessage = UserManagementMessages.CommandExecutionFailed(ex.Message);
UserManagementServiceLog.CommandExecutionFailed(Logger, command.GetType().Name, ex.Message, ex);
return GenericResult.Failure(errorMessage);
}
}
}
Component Rules and Placement
Strict Placement Rules
Abstractions Project (netstandard2.0)
| Component | Location | Purpose | Naming Pattern |
|---|---|---|---|
| Service Interfaces | Services/ |
Domain contracts | I{Domain}Service |
| Command Base Classes | Commands/ |
Operation contracts | {Domain}Command |
| Configuration Interfaces | Configuration/ |
Settings contracts | I{Domain}Configuration |
| Message Base Classes | Messages/ |
Communication contracts | {Domain}Message |
| Logging Signatures | Logging/ |
Telemetry contracts | {Domain}ServiceLog |
Concrete Project (target framework)
| Component | Location | Purpose | Naming Pattern |
|---|---|---|---|
| Service Base Classes | Services/ |
Implementation foundations | {Domain}ServiceBase |
| Configuration Classes | Configuration/ |
Settings implementations | {Domain}Configuration |
| Factory Base Classes | Factories/ |
Creation patterns | {Domain}FactoryBase |
| ServiceType Registration | ServiceTypes/ |
Framework integration | {Domain}ServiceType |
| Provider Implementation | Registration/ |
Service resolution | {Domain}ServiceProvider |
| Registration Options | Registration/ |
DI configuration | {Domain}RegistrationOptions |
Component Syntax Rules
Service Interface Hierarchy
// ✅ Correct: Abstractions project
namespace MyCompany.Services.UserManagement.Abstractions.Services;
/// <summary>
/// Defines user management operations for any implementation.
/// </summary>
public interface IUserManagementService : IGenericService<UserManagementCommand, IUserManagementConfiguration>
{
/// <summary>
/// Creates a new user account.
/// </summary>
Task<IGenericResult<UserCreatedResult>> CreateUser(CreateUserCommand command);
/// <summary>
/// Authenticates user credentials.
/// </summary>
Task<IGenericResult<AuthenticationResult>> Authenticate(AuthenticateUserCommand command);
}
// ❌ Incorrect: Generic constraints missing
public interface IUserManagementService : IGenericService
// ❌ Incorrect: Wrong namespace
namespace MyCompany.Services.UserManagement.Services;
Command Hierarchy Rules
// ✅ Correct: Abstractions project base command
namespace MyCompany.Services.UserManagement.Abstractions.Commands;
/// <summary>
/// Base class for all user management operations.
/// </summary>
public abstract class UserManagementCommand : ICommand
{
/// <summary>
/// Gets or sets the command identifier.
/// </summary>
public string CommandId { get; set; } = Guid.NewGuid().ToString();
/// <summary>
/// Gets or sets when the command was created.
/// </summary>
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
/// <summary>
/// Gets or sets the user who initiated the command.
/// </summary>
public string? InitiatedBy { get; set; }
}
// ✅ Correct: Specific command implementations
/// <summary>
/// Command to create a new user account.
/// </summary>
public class CreateUserCommand : UserManagementCommand
{
public string Username { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public Dictionary<string, object> Properties { get; set; } = new();
}
// ❌ Incorrect: Missing inheritance
public class CreateUserCommand : ICommand
// ❌ Incorrect: Wrong namespace or project
namespace MyCompany.Services.UserManagement.Commands;
Core Interface Hierarchy
Service Interface Evolution
The framework provides a progressive interface hierarchy that adds capabilities:
// Level 1: Basic service identification
public interface IGenericService
{
string Id { get; } // Unique instance identifier
string ServiceType { get; } // Service type name for logging
bool IsAvailable { get; } // Runtime availability status
}
// Level 2: Command execution capability
public interface IGenericService<TCommand> : IGenericService
where TCommand : ICommand
{
Task<IGenericResult> Execute(TCommand command);
}
// Level 3: Configuration access and typed execution
public interface IGenericService<TCommand, TConfiguration> : IGenericService<TCommand>
where TCommand : ICommand
where TConfiguration : IGenericConfiguration
{
string Name { get; } // Display name from configuration
TConfiguration Configuration { get; } // Strongly-typed configuration access
// Generic execution with typed results
Task<IGenericResult<T>> Execute<T>(TCommand command);
Task<IGenericResult<TOut>> Execute<TOut>(TCommand command, CancellationToken cancellationToken);
Task<IGenericResult> Execute(TCommand command, CancellationToken cancellationToken);
}
// Level 4: Type identification for logging and DI
public interface IGenericService<TCommand, TConfiguration, TService> : IGenericService<TCommand, TConfiguration>
where TCommand : ICommand
where TConfiguration : IGenericConfiguration
where TService : class
{
// TService provides compile-time type information for:
// - Generic logging with ILogger<TService>
// - DI registration with proper lifetimes
// - Source generator type discovery
// - Performance profiling and monitoring
}
Command System
Command Architecture Principles
Commands represent operations that can be performed within a domain. They:
- Encapsulate operation data and validation
- Provide a uniform execution model
- Enable cross-cutting concerns (logging, metrics, caching)
- Support command composition and chaining
Command Hierarchy Design
// ✅ Correct: Domain command hierarchy
namespace MyCompany.Services.UserManagement.Abstractions.Commands;
/// <summary>
/// Base class for all user management operations.
/// Provides common audit trail and metadata.
/// </summary>
public abstract class UserManagementCommand : ICommand
{
/// <summary>
/// Unique identifier for this command instance.
/// Used for correlation across logging and monitoring.
/// </summary>
public string CommandId { get; init; } = Guid.NewGuid().ToString();
/// <summary>
/// Timestamp when the command was created.
/// Used for performance monitoring and audit trails.
/// </summary>
public DateTime CreatedAt { get; init; } = DateTime.UtcNow;
/// <summary>
/// Identity of the user who initiated this command.
/// Used for authorization and audit logging.
/// </summary>
public string? InitiatedBy { get; init; }
/// <summary>
/// Additional context data for this command.
/// Used for cross-cutting concerns and extensibility.
/// </summary>
public Dictionary<string, object> Context { get; init; } = new();
}
/// <summary>
/// Commands that modify user data.
/// Adds transaction and concurrency control metadata.
/// </summary>
public abstract class UserManagementMutationCommand : UserManagementCommand
{
/// <summary>
/// Expected version for optimistic concurrency control.
/// Prevents lost update scenarios.
/// </summary>
public string? ExpectedVersion { get; init; }
/// <summary>
/// Whether this command should participate in a transaction.
/// Enables batch operation support.
/// </summary>
public bool RequiresTransaction { get; init; } = true;
}
/// <summary>
/// Commands that only read user data.
/// Optimized for caching and read scaling.
/// </summary>
public abstract class UserManagementQueryCommand : UserManagementCommand
{
/// <summary>
/// Whether cached results are acceptable.
/// Enables performance optimization for read-heavy scenarios.
/// </summary>
public bool AllowCachedResults { get; init; } = true;
/// <summary>
/// Maximum age of cached results in seconds.
/// Balances consistency with performance.
/// </summary>
public int CacheMaxAgeSeconds { get; init; } = 300;
}
Configuration System
Configuration Architecture
Configuration in domain services follows a interface-first, validation-required pattern:
// ✅ Correct: Abstractions project interface
namespace MyCompany.Services.UserManagement.Abstractions.Configuration;
/// <summary>
/// Configuration contract for user management services.
/// Defines all settings required by any implementation.
/// </summary>
public interface IUserManagementConfiguration : IGenericConfiguration
{
/// <summary>
/// Primary data store connection string.
/// Used for user account storage and retrieval.
/// </summary>
string ConnectionString { get; }
/// <summary>
/// Password policy configuration.
/// Defines complexity requirements and expiration rules.
/// </summary>
PasswordPolicy PasswordPolicy { get; }
/// <summary>
/// Session management settings.
/// Controls timeout and concurrent session limits.
/// </summary>
SessionConfiguration SessionSettings { get; }
}
Factory System
Factory Architecture
The factory system provides type-safe service creation with configuration validation:
// ✅ Correct: Use GenericServiceFactory for standard services
namespace MyCompany.Services.UserManagement.ServiceTypes;
public class UserManagementServiceType : ServiceTypeBase<IUserManagementService, GenericServiceFactory<IUserManagementService, UserManagementConfiguration, UserManagementConfiguration>>
{
public UserManagementServiceType() : base(100, "UserManagement", "UserServices") { }
public override string SectionName => "Services:UserManagement";
public override string DisplayName => "User Management Service";
public override string Description => "Manages user accounts, authentication, and profiles";
public override void Register(IServiceCollection services)
{
// Register the generic factory - no custom factory needed
services.AddScoped<GenericServiceFactory<IUserManagementService, UserManagementConfiguration>>();
// Register service implementations
services.AddTransient<IUserManagementService, DatabaseUserManagementService>();
}
}
Provider System
Domain Service Provider Architecture
The DomainServiceProvider abstracts service resolution within a domain:
// ✅ Correct: Domain service provider interface
namespace MyCompany.Services.UserManagement.Abstractions;
/// <summary>
/// Provides access to user management services without knowing specific implementations.
/// </summary>
public interface IUserManagementServiceProvider : IGenericServiceProvider
{
/// <summary>
/// Gets the default user management service.
/// Implementation selected based on configuration priority.
/// </summary>
Task<IGenericResult<IUserManagementService>> GetService();
/// <summary>
/// Gets a user management service using a named configuration.
/// </summary>
Task<IGenericResult<IUserManagementService>> GetService(string configurationName);
/// <summary>
/// Gets a specific user management service implementation.
/// </summary>
Task<IGenericResult<TService>> GetService<TService>() where TService : class, IUserManagementService;
}
Message Integration
Message System Architecture
Messages provide structured communication between services and with external systems:
// ✅ Correct: Domain message base class
namespace MyCompany.Services.UserManagement.Abstractions.Messages;
/// <summary>
/// Base class for all user management messages.
/// Provides consistent structure and source generation support.
/// </summary>
[MessageCollection("UserManagementMessages")]
public abstract class UserManagementMessage : MessageTemplate<MessageSeverity>, IServiceMessage
{
/// <summary>
/// Initializes a new instance of the UserManagementMessage class.
/// </summary>
protected UserManagementMessage(int id, string name, MessageSeverity severity,
string message, string? code = null)
: base(id, name, severity, "UserManagement", message, code, null, null) { }
}
Generic Constraints Reference
Service Interface Constraints
// ✅ Correct: Progressive constraint addition
public interface IGenericService
// No constraints - basic service contract
public interface IGenericService<TCommand> : IGenericService
where TCommand : ICommand
// TCommand must implement ICommand - ensures command pattern compliance
public interface IGenericService<TCommand, TConfiguration> : IGenericService<TCommand>
where TCommand : ICommand
where TConfiguration : IGenericConfiguration
// TConfiguration must implement IGenericConfiguration - ensures validation and binding support
public interface IGenericService<TCommand, TConfiguration, TService> : IGenericService<TCommand, TConfiguration>
where TCommand : ICommand
where TConfiguration : IGenericConfiguration
where TService : class
// TService must be a reference type - enables logging and DI type identification
Factory Interface Constraints
// ✅ Correct: Factory constraint patterns
public interface IServiceFactory<TService> : IServiceFactory
where TService : class
// TService must be reference type - prevents value type services
public interface IServiceFactory<TService, TConfiguration> : IServiceFactory<TService>
where TService : class
where TConfiguration : class, IGenericConfiguration
// TConfiguration must be reference type AND implement IGenericConfiguration
// class constraint required for configuration binding and caching
Constraint Selection Rules
Reference Type Constraints (class)
Always required for:
- Service types (enables DI registration)
- Configuration types (enables binding and caching)
- Factory types (enables reflection and instantiation)
Interface Constraints
ICommand Constraint:
- Required on command type parameters
- Ensures Execute method compatibility
- Enables command pattern infrastructure
IGenericService Constraint:
- Required on service type parameters
- Ensures service contract compliance
- Enables service infrastructure integration
IGenericConfiguration Constraint:
- Required on configuration type parameters
- Ensures validation and binding support
- Enables configuration infrastructure integration
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- FluentValidation (>= 11.9.2)
- FractalDataWorks.Abstractions (>= 0.7.0-alpha.1022)
- FractalDataWorks.Collections (>= 0.7.0-alpha.1022)
- FractalDataWorks.Messages (>= 0.7.0-alpha.1022)
- FractalDataWorks.Results (>= 0.7.0-alpha.1022)
- FractalDataWorks.ServiceTypes (>= 0.7.0-alpha.1022)
- Microsoft.Extensions.Configuration (>= 10.0.0-rc.2.25502.107)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0-rc.2.25502.107)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.0-rc.2.25502.107)
NuGet packages (15)
Showing the top 5 NuGet packages that depend on FractalDataWorks.Services.Abstractions:
| Package | Downloads |
|---|---|
|
FractalDataWorks.Services
Development tools and utilities for the FractalDataWorks ecosystem. Build: |
|
|
FractalDataWorks.Services.Scheduling.Abstractions
Development tools and utilities for the FractalDataWorks ecosystem. Build: |
|
|
FractalDataWorks.Services.Transformations.Abstractions
Development tools and utilities for the FractalDataWorks ecosystem. Build: |
|
|
FractalDataWorks.Services.Connections.Abstractions
Development tools and utilities for the FractalDataWorks ecosystem. Build: |
|
|
FractalDataWorks.Services.Execution.Abstractions
Development tools and utilities for the FractalDataWorks ecosystem. Build: |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.7.0-alpha.1022 | 149 | 11/3/2025 |
| 0.7.0-alpha.1021 | 156 | 11/3/2025 |
| 0.7.0-alpha.1008 | 107 | 11/2/2025 |
| 0.7.0-alpha.1006 | 136 | 10/30/2025 |
| 0.7.0-alpha.1005 | 132 | 10/30/2025 |
| 0.7.0-alpha.1004 | 137 | 10/30/2025 |
| 0.7.0-alpha.1001 | 134 | 10/29/2025 |
| 0.6.0-alpha.1006 | 129 | 10/29/2025 |
| 0.6.0-alpha.1005 | 126 | 10/28/2025 |
| 0.6.0-alpha.1004 | 126 | 10/28/2025 |