Codebelt

Savvyio.Extensions.DependencyInjection.EFCore

Marker-aware DI registrations for EF Core-backed Savvy I/O data sources, repositories, and data stores.

.NET 10.0 / .NET 9.0 MIT v5.0.8 11,774 downloads

Overview

Savvyio.Extensions.DependencyInjection.EFCore adds Microsoft Dependency Injection registrations for the EF Core-backed Savvy I/O data source, repository, and data store types. It extends Savvyio.Extensions.DependencyInjection with marker-aware wrappers over the lower-level Savvyio.Extensions.EFCore types so one container can host multiple EF Core implementations side by side.

Most of the public surface is about DI composition rather than new persistence behavior. The package supplies generic marker types, thin wrapper classes, and service-collection extensions that forward registrations into the Savvy I/O abstractions consumers already resolve.

Key APIs

AddEfCoreDataSource registers EfCoreDataSource or EfCoreDataSource<TMarker> in IServiceCollection, adds corresponding unit of work registrations, and stores configured EfCoreDataSourceOptions through AddConfiguredOptions. Tests show the registered service resolves through both IEfCoreDataSource and IUnitOfWork, or their marker-specific counterparts.

AddEfCoreRepository adds EfCoreRepository<TEntity, TKey> or EfCoreRepository<TEntity, TKey, TMarker> and forwards it to the Savvy I/O repository interfaces for reading, writing, searching, and deleting entities that satisfy IIdentity<TKey>.

AddEfCoreDataStore adds EfCoreDataStore<T> or EfCoreDataStore<T, TMarker> and forwards it to the marker-aware persistent data store abstractions for DTO-style CRUD access over EfCoreQueryOptions<T>.

IEfCoreDataSource<TMarker> combines the lower-level IEfCoreDataSource contract with IDataSource<TMarker> and IUnitOfWork<TMarker>, making the marker part of both data access and transaction resolution.

EfCoreDataSourceOptions<TMarker> is the marker-specific configuration object used when creating EfCoreDataSource<TMarker> and EfCoreDbContext<TMarker>. It inherits the lower-level EF Core options type, so the same context configuration hooks are available while DI can distinguish one implementation from another.

EfCoreDbContext<TMarker> is the marker-aware DbContext wrapper constructed from EfCoreDataSourceOptions<TMarker>. It exists so a marker-specific EfCoreDataSource<TMarker> can build its own EF Core context instance from the same options object registered in the container.

EfCoreRepository<TEntity, TKey, TMarker> is the marker-specific repository wrapper over EfCoreRepository<TEntity, TKey>. Its constructor takes IEfCoreDataSource<TMarker>, which lets the built-in container resolve different repository implementations for the same entity type by marker.

EfCoreDataStore<T, TMarker> is the marker-specific data store wrapper over EfCoreDataStore<T>. Its constructor also takes IEfCoreDataSource<TMarker>, so marker-scoped data stores can share the matching EF Core data source and unit of work registration.

Basic usage

using System.Linq;
using Codebelt.Extensions.Xunit;
using Microsoft.Extensions.DependencyInjection;
using Savvyio.Extensions.DependencyInjection.EFCore;
using Xunit;

namespace MyProject.Tests;

public class EfCoreRegistrationTests : Test
{
    public EfCoreRegistrationTests(ITestOutputHelper output) : base(output) { }

    [Fact]
    public void AddEfCoreDataStore_ConfiguredMarker_RegistersServices()
    {
        var services = new ServiceCollection();
        services.AddEfCoreDataSource<ReadModelMarker>(o => o.ContextConfigurator = _ => { });
        services.AddEfCoreDataStore<LedgerRow, ReadModelMarker>();

        TestOutput.WriteLine($"Registered services: {services.Count}");
        Assert.Contains(services, d => d.ServiceType == typeof(IEfCoreDataSource<ReadModelMarker>));
        Assert.Contains(services, d => d.ServiceType.Name.Contains("IPersistentDataStore"));
    }
}

public sealed class ReadModelMarker { }
public sealed class LedgerRow { }

Use this pattern when one container needs the EF Core registrations added before a provider is built. It matters because the package contributes marker-specific service descriptors without requiring manual DI wiring.

Installation

dotnet add package Savvyio.Extensions.DependencyInjection.EFCore

Usage guidance

Choose this package when your application already uses Savvy I/O abstractions and you want EF Core implementations to participate in Microsoft Dependency Injection, especially when markers separate multiple data sources or repositories in the same container. If you only need the EF Core persistence types themselves, Savvyio.Extensions.EFCore is the smaller dependency, and if you do not need Savvy I/O abstractions at all, plain EF Core registrations are the simpler option.

Family packages