Xpandables.Net.EntityFramework 7.0.0-rc2.0.1

This is a prerelease version of Xpandables.Net.EntityFramework.
There is a newer version of this package available.
See the version list below for details.
dotnet add package Xpandables.Net.EntityFramework --version 7.0.0-rc2.0.1
                    
NuGet\Install-Package Xpandables.Net.EntityFramework -Version 7.0.0-rc2.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Xpandables.Net.EntityFramework" Version="7.0.0-rc2.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Xpandables.Net.EntityFramework" Version="7.0.0-rc2.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Xpandables.Net.EntityFramework" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Xpandables.Net.EntityFramework --version 7.0.0-rc2.0.1
                    
#r "nuget: Xpandables.Net.EntityFramework, 7.0.0-rc2.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Xpandables.Net.EntityFramework@7.0.0-rc2.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Xpandables.Net.EntityFramework&version=7.0.0-rc2.0.1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Xpandables.Net.EntityFramework&version=7.0.0-rc2.0.1&prerelease
                    
Install as a Cake Tool

Xpandables.Net

Provides with useful interfaces contracts in .Net 7.0 and some implementations mostly following the spirit of SOLID principles, CQRS... The library is strongly-typed, which means it should be hard to make invalid requests and it also makes it easy to discover available methods and properties though IntelliSense.

Feel free to fork this project, make your own changes and create a pull request.

Read the Xpandables.Net.Samples for a minimal Web Api implementation using multi-tenancy with aggregates. You may need to create a PostgreSql database using the migration definitions.

Features

Usually, when registering types, we are forced to reference the libraries concerned and we end up with a very coupled set. To avoid this, you can register these types by calling an export extension method, which uses MEF: Managed Extensibility Framework.

In your api startup class


// AddXServiceExport(IConfiguration, Action{ExportServiceOptions}) adds and configures registration of services using 
// the IAddServiceExport interface implementation found in the target libraries according to the export options.
// You can use configuration file to set up the libraries to be scanned.

public class Startup
{
    ....
    services
        .AddXServices()
            .AddXServiceExport(Configuration, options => options.SearchPattern = "your-search-pattern-dll")
        .Build();
    ...
}

In the library you want types to be registered


[Export(typeof(IAddServiceExport))]
public sealed class RegisterServiceExport : IAddServiceExport
{
    public void AddServices(IServiceCollection services, IConfiguration configuration)
    {
        services
            .AddXServices()
                .AddXCommandDispatcher()
                ...
            .Build();
        ....
    }
}

Decorator pattern

You can use the extension methods to apply the decorator pattern to your types.


// This method and its extensions ensure that the supplied TDecorator" decorator is returned, wrapping the original 
// registered "TService", by injecting that service type into the constructor of the supplied "TDecorator". 
// Multiple decorators may be applied to the same "TService". By default, a new "TDecorator" instance 
// will be returned on each request, 
// independently of the lifestyle of the wrapped service. Multiple decorators can be applied to the same service type. 
// The order in which they are registered is the order they get applied in. This means that the decorator 
// that gets registered first, gets applied first, which means that the next registered decorator, 
// will wrap the first decorator, which wraps the original service type.

 services
    .AddXServices()
        .XTryDecorate<TService, TDecorator>()
    .Build();
   

Suppose you want to add logging for the AddPersonCommand ...


// The AddPersonCommand decorator for logging

public sealed class AddPersonCommandHandlerLoggingDecorator : 
    ICommandHandler<AddPersonCommand>
{
    private readonly ICommandHandler<AddPersonCommand> _decoratee;
    private readonly ILogger<AddPersonCommandHandler> _logger;
    
    public AddPersonCommandHandlerLoggingDecorator(
        ILogger<AddPersonCommandHandler> logger,
        ICommandHandler<AddPersonCommand> decoratee)
        => (_logger, _decoratee) = (logger, decoratee);

    public async ValueTask<OperationResult> HandleAsync(
        AddPersonCommand command, CancellationToken cancellationToken = default)
    {
        _logger.Information(...);
        
        var response = await _decoratee.HandleAsync(command, cancellationToken).configureAwait(false);
        
        _logger.Information(...)
        
        return response;
    }
}

// Register

services
    .AddXServices()
        .XTryDecorate<AddPersonCommandHandler, AddPersonCommandHandlerLoggingDecorator>()
    .Build();

 // or

services.AddXServices()
    .AddXHandlers(
        options =>
        {
            options.UseValidatorDecorator(); // this option will add the command decorator registration
        },
        typeof(AddPersonCommandHandler).Assembly)
    .Build()

// or you can define the generic model, for all commands that implement ICommand 
// interface or something else.

public sealed class CommandLoggingDecorator<TCommand> : ICommandHandler<TCommand>
    where TCommand : notnull, ICommand // you can add more constraints
{
    private readonly ICommandHandler<TCommand> _ decoratee;
    private readonly ILogger<TCommand> _logger;
    
    public CommandLoggingDecorator(ILogger<TCommand> logger, ICommandHandler<TCommand> decoratee)
        => (_logger, _ decoratee) = (logger, decoratee);

    public async ValueTask<OperationResult> HandleAsync(
         TCommand command, CancellationToken cancellationToken = default)
    {
        _logger.Information(...);
        
        var response = await _decoratee.HandleAsync(command, cancellationToken).configureAwait(false);
        
        _logger.Information(...)
        
        return response;
    }
}

// and for registration

// The CommandLoggingDecorator will be applied to all command handlers whose commands meet 
// the decorator's constraints : 
// To be a notnull and implement ICommand interface

services
    .AddXServices()
        .XTryDecorate(typeof(ICommandHandler<>), typeof(CommandLoggingDecorator<>))
    .Build();

Aggregate{TAggregateId}

Libraries also provide with DDD model implementation 'Aggregate{TAggregateId}' using event sourcing and out-box pattern.

Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Xpandables.Net.EntityFramework:

Package Downloads
Xpandables.Net.EntityFramework.DependencyInjection

A utility library in .Net5 that adds dependency injection to Xpandables.Net.EntityFramework

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
9.3.4 261 4/27/2025
9.3.2 277 4/20/2025
9.3.0 305 4/14/2025
9.1.2 270 3/12/2025
9.1.0 301 3/8/2025
9.0.1 218 1/19/2025
9.0.0-rc.1 90 10/26/2024
8.1.2 249 9/12/2024
8.0.8 251 6/21/2024
8.0.6 236 5/25/2024
8.0.5 234 5/18/2024
8.0.1 271 2/11/2024
8.0.0 232 12/3/2023
8.0.0-rc.2.1.1 155 11/12/2023
8.0.0-rc.2.1 112 11/6/2023
8.0.0-rc.2.0 130 11/5/2023
7.3.3 359 5/9/2023
7.1.4 432 2/26/2023
7.1.3 402 2/19/2023
7.0.0 510 11/9/2022
7.0.0-rc2.0.1 233 10/12/2022
7.0.0-rc1.0.0 256 9/26/2022
6.1.1 612 8/6/2022
6.0.9 663 7/9/2022
6.0.8 632 6/27/2022
6.0.4 665 3/15/2022
6.0.3 613 2/22/2022
6.0.2 499 1/4/2022
6.0.1 489 12/4/2021
6.0.0 540 11/8/2021
6.0.0-rc.4.3 293 11/3/2021
6.0.0-rc.3.1 289 10/15/2021
6.0.0-rc.3 307 10/14/2021
6.0.0-rc.2 306 9/21/2021
6.0.0-preview.5 294 8/26/2021
5.6.1 580 6/30/2021
5.6.0 601 6/9/2021
5.5.1 574 5/26/2021
5.4.4 512 4/12/2021
5.4.0 660 3/11/2021
5.3.14 637 3/2/2021
5.3.13 610 2/25/2021
5.3.12 588 2/21/2021
5.3.11 570 2/18/2021
5.3.10 563 2/18/2021
5.3.9 599 2/11/2021
5.3.8 608 2/10/2021
5.3.7 595 2/7/2021
5.3.5 556 2/7/2021
5.3.4 575 2/7/2021
5.3.3 584 2/5/2021
5.3.2 568 2/2/2021
5.3.1 625 1/31/2021
5.3.0 608 1/31/2021
5.2.14 665 1/26/2021
5.2.13 606 1/25/2021
5.2.12 615 1/22/2021
5.2.11 622 1/19/2021
5.2.10 590 1/16/2021
5.2.9 581 1/13/2021
5.2.8 610 1/8/2021
5.2.7 639 1/6/2021
5.2.6 658 1/6/2021
5.2.5 671 12/17/2020
5.2.4 638 12/12/2020
5.2.3 624 12/8/2020
5.2.2 617 12/7/2020
5.2.1 648 12/7/2020
5.2.0 832 12/6/2020
5.1.1 758 12/6/2020
5.1.0 616 12/5/2020
5.0.6 654 12/5/2020
5.0.5 625 11/23/2020
5.0.4 616 11/22/2020
5.0.3 753 11/20/2020
5.0.2 676 11/19/2020
5.0.1 688 11/16/2020
5.0.0 631 11/12/2020
5.0.0-rc.2.1.4 432 11/6/2020
5.0.0-rc.2.1.3 440 11/1/2020
5.0.0-rc.2.1.2 405 10/31/2020
5.0.0-rc.2.1.0 456 10/24/2020
5.0.0-rc.2.0.2 358 10/22/2020
5.0.0-rc.2.0.1 408 10/17/2020
5.0.0-rc.2.0.0 405 10/17/2020
5.0.0-rc.1.1.5 455 10/11/2020
5.0.0-rc.1.1.4 458 10/11/2020
5.0.0-rc.1.1.3 511 10/10/2020
5.0.0-rc.1.1.2 397 10/4/2020
5.0.0-rc.1.1.1 404 10/2/2020
5.0.0-rc.1.1.0 383 10/1/2020
5.0.0-rc.1.0.9 423 9/29/2020
5.0.0-rc.1.0.8 373 9/28/2020
5.0.0-rc.1.0.7 412 9/28/2020
5.0.0-rc.1.0.6 450 9/26/2020
5.0.0-rc.1.0.5 419 9/25/2020
5.0.0-rc.1.0.4 389 9/24/2020
5.0.0-rc.1.0.3 450 9/23/2020
5.0.0-rc.1.0.2 404 9/23/2020
5.0.0-rc.1.0.1 392 9/21/2020
5.0.0-preview.2.0.0 380 8/16/2020
5.0.0-preview.1.0.8 386 8/10/2020
5.0.0-preview.1.0.7 460 8/10/2020
5.0.0-preview.1.0.6 462 8/5/2020
3.2.1 697 9/17/2020
3.2.0 711 9/15/2020
3.1.9 670 9/13/2020
3.1.8 733 9/13/2020
3.1.7 660 9/12/2020
3.1.6 827 9/5/2020
3.1.5 680 9/4/2020
3.1.4 767 8/29/2020
3.1.3 690 8/28/2020
3.1.2 676 8/27/2020
3.1.1 663 8/24/2020
3.1.0 691 8/19/2020

Add the data context and related types.