Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge 17-dependencyinjection-fails-validation-for-events-although-events-not-used into main #18

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>1.0.0-beta-2</Version>
Expand All @@ -14,7 +14,7 @@
<RepositoryType>git</RepositoryType>
<PackageTags>EventSourcing, Events, EventStore</PackageTags>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageVersion>1.0.0-beta-6</PackageVersion>
<PackageVersion>1.0.0-preview-20240513-0708</PackageVersion>
<PackageReleaseNotes>Braking Changes - New Mapper Logic</PackageReleaseNotes>
<RootNamespace>EventSourcing</RootNamespace>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>1.0.0-beta006</Version>
<Version>1.0.0-preview-20240513-0708</Version>
<Title>EventSourcing.Publishers.RabbitMQ</Title>
<Authors>Andreas Naumann</Authors>
<Description>Extend the event sourcing system with RabbitMQ.
Expand Down
4 changes: 2 additions & 2 deletions src/EventSourcing.Publishers/EventSourcing.Publishers.csproj
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>1.0.0-beta006</Version>
<Version>1.0.0-preview-20240513-0708</Version>
<Title>EventSourcing.Publishers</Title>
<Authors>Andreas Naumann</Authors>
<Description>Extend the event sourcing system with publishers like Mqtt or RabbitMQ</Description>
Expand Down
3 changes: 3 additions & 0 deletions src/EventSourcing/DI/EventMappingOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Microsoft.Extensions.DependencyInjection;

public record EventMappingOptions(IServiceCollection Services, IEnumerable<Type> CoveredEvents, IEnumerable<Type>? UncoveredEvents = null);
28 changes: 10 additions & 18 deletions src/EventSourcing/DI/EventMappingOptionsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,14 @@ namespace Microsoft.Extensions.DependencyInjection;

public class EventMappingOptionsBuilder
{
private readonly IServiceCollection _services;
private readonly List<Type> _mappersToRegister = new();
private readonly List<EventMapperAssembly> _assembliesToRegisterMappers = new();
private bool _ignoreUncoveredEvents = false;

public EventMappingOptionsBuilder(IServiceCollection services)
public EventMappingOptionsBuilder()
{
_services = services;
}

public EventMappingOptionsBuilder AddMappers(bool registerDefaultMappers = true)
{
_assembliesToRegisterMappers.Add(new EventMapperAssembly(Assembly.GetEntryAssembly()!, registerDefaultMappers));
return this;
}

public EventMappingOptionsBuilder AddMappers(Assembly assembly, bool registerDefaultMappers = true)
{
_assembliesToRegisterMappers.Add(new EventMapperAssembly(assembly, registerDefaultMappers));
Expand All @@ -43,9 +35,10 @@ public EventMappingOptionsBuilder IgnoreUncoveredEvents()
return this;
}

public void Build()
public EventMappingOptions Build()
{
_services.AddScoped<IEventRegistry, EventRegistry>();
var services = new ServiceCollection();
services.AddScoped<IEventRegistry, EventRegistry>();
var eventMappers = new List<EventMapperType> ();
foreach (var assembly in _assembliesToRegisterMappers)
{
Expand All @@ -70,7 +63,7 @@ public void Build()
}

foreach (var eventMapper in eventMappers)
_services.TryAddEnumerable(ServiceDescriptor.Transient(typeof(IEventMapper), eventMapper.Type));
services.TryAddEnumerable(ServiceDescriptor.Transient(typeof(IEventMapper), eventMapper.Type));

var alreadyCoveredEvents = eventMappers.Select(mapper => mapper.EventType).ToList();
foreach (var assembly in _assembliesToRegisterMappers.Where(a => a.RegisterDefaultMappers))
Expand All @@ -85,7 +78,7 @@ public void Build()
if (alreadyCoveredEvents.Contains(eventType)) continue;

var defaultEventMapperType = typeof(DefaultEventMapper<>).MakeGenericType(eventType);
_services.TryAddEnumerable(ServiceDescriptor.Transient(typeof(IEventMapper), defaultEventMapperType));
services.TryAddEnumerable(ServiceDescriptor.Transient(typeof(IEventMapper), defaultEventMapperType));
alreadyCoveredEvents.Add(eventType);
}
}
Expand All @@ -98,17 +91,16 @@ public void Build()
.GetGenericArguments()[0];
if (alreadyCoveredEvents.Contains(eventType))
throw new InvalidOperationException($"The mapper {mapper.Name} cannot be registered by the AddMapper<TEventMapper>() method.\nThere is already an event mapper for the event type {eventType.Name}.");
_services.TryAddEnumerable(ServiceDescriptor.Transient(typeof(IEventMapper), mapper));
services.TryAddEnumerable(ServiceDescriptor.Transient(typeof(IEventMapper), mapper));
alreadyCoveredEvents.Add(eventType);
}

var uncoveredEvents = _assembliesToRegisterMappers.SelectMany(assembly => assembly.Assembly.GetTypes()
.Where(t => t is { IsAbstract: false, IsInterface: false } && t.GetInterfaces().Any(i => i == typeof(IEvent)) && !alreadyCoveredEvents.Contains(t))).ToList();

foreach(var eventType in alreadyCoveredEvents)
_services.TryAddEnumerable(ServiceDescriptor.Transient(typeof(IEvent), eventType));

if (_ignoreUncoveredEvents || !uncoveredEvents.Any()) return;
if (_ignoreUncoveredEvents || !uncoveredEvents.Any())
return new EventMappingOptions(services, alreadyCoveredEvents, uncoveredEvents);

var uncoveredEventNames = string.Join(", ", uncoveredEvents.Select(x => x.Name));
throw new InvalidOperationException($"There are uncovered events (in mappings): {uncoveredEventNames}");
}
Expand Down
3 changes: 3 additions & 0 deletions src/EventSourcing/DI/EventProjectionOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Microsoft.Extensions.DependencyInjection;

public record EventProjectionOptions(IServiceCollection Services, IEnumerable<Type> CoveredEvents, IEnumerable<Type>? UncoveredEvents);
19 changes: 9 additions & 10 deletions src/EventSourcing/DI/EventProjectionOptionsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@ namespace Microsoft.Extensions.DependencyInjection;

public class EventProjectionOptionsBuilder
{
private readonly IServiceCollection _services;
private readonly List<EventProjectionAssembly> _assembliesToRegisterProjections = new();
private bool _ignoreUncoveredEvents;

public EventProjectionOptionsBuilder(IServiceCollection services)
public EventProjectionOptionsBuilder()
{
_services = services;
}

public EventProjectionOptionsBuilder AddProjections()
Expand All @@ -34,8 +32,9 @@ public EventProjectionOptionsBuilder IgnoreUncoveredEvents()
return this;
}

public void Build()
public EventProjectionOptions Build(IEnumerable<Type>? recentlyFoundEvents = null)
{
var services = new ServiceCollection();
var projectionTypes = new List<ProjectionType>();
foreach (var assembly in _assembliesToRegisterProjections)
{
Expand All @@ -52,15 +51,15 @@ public void Build()
foreach (var projectionType in projectionTypes)
{
var genericType = typeof(IEventHandler<>).MakeGenericType(projectionType.EventType);
_services.TryAddEnumerable(ServiceDescriptor.Transient(genericType, projectionType.Type));
_services.TryAddEnumerable(ServiceDescriptor.Transient(typeof(IEventHandler), projectionType.Type));
services.TryAddEnumerable(ServiceDescriptor.Transient(genericType, projectionType.Type));
services.TryAddEnumerable(ServiceDescriptor.Transient(typeof(IEventHandler), projectionType.Type));
alreadyCoveredEvents.Add(projectionType.EventType);
}

if (_ignoreUncoveredEvents) return;
var allEvents = _services.Where(descriptor => descriptor.ServiceType == typeof(IEvent)).Select(descriptor => descriptor.ImplementationType).ToList();
var uncoveredEvents = allEvents.Except(alreadyCoveredEvents).ToList();
if (!uncoveredEvents.Any()) return;
var uncoveredEvents = (recentlyFoundEvents ?? new List<Type>()).Except(alreadyCoveredEvents).ToList();
if (_ignoreUncoveredEvents || !uncoveredEvents.Any())
return new EventProjectionOptions(services, alreadyCoveredEvents, uncoveredEvents);

var uncoveredEventNames = string.Join(", ", uncoveredEvents.Select(x => x?.FullName));
throw new InvalidOperationException($"There are uncovered events (in projections): {uncoveredEventNames}");
}
Expand Down
24 changes: 16 additions & 8 deletions src/EventSourcing/DI/EventSourcingOptionsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public class EventSourcingOptionsBuilder
public EventSourcingOptionsBuilder(IServiceCollection services)
{
_services = services;
_eventMappingOptionsBuilder = new EventMappingOptionsBuilder(services);
_eventProjectionOptionsBuilder = new EventProjectionOptionsBuilder(services);
_eventMappingOptionsBuilder = new EventMappingOptionsBuilder();
_eventProjectionOptionsBuilder = new EventProjectionOptionsBuilder();
}

/// <summary>
Expand Down Expand Up @@ -88,19 +88,27 @@ public EventSourcingOptionsBuilder Extend(Action<IServiceCollection> extension)
public void Build()
{
if (!_databaseConfigured)
_dbContextOptionsBuilderAction = options => options.UseInMemoryDatabase("EventStore");
throw new InvalidOperationException("The event store database context must be configured.");
if (!_mappingConfigured)
throw new InvalidOperationException("The event mapping must be configured.");
if (!_projectionsConfigured)
throw new InvalidOperationException("The event projections must be configured.");

_services.AddDbContext<IEventStoreDbContext, EventStoreDbContext>(opt => _dbContextOptionsBuilderAction?.Invoke(opt));
_services.AddScoped<IEventStore, EventStore>();
_services.AddScoped<IEventRepository, EventRepository>();
_services.AddTransient<IEventBus, EventBus>();

if (!_mappingConfigured)
_eventMappingOptionsBuilder.AddMappers();

if (!_projectionsConfigured)
_eventProjectionOptionsBuilder.AddProjections();

_eventMappingOptionsBuilder.Build();
_eventProjectionOptionsBuilder.Build();
var eventMappingOptions = _eventMappingOptionsBuilder.Build();
foreach (var service in eventMappingOptions.Services)
_services.Add(service);

var eventProjectionOptions = _eventProjectionOptionsBuilder.Build(eventMappingOptions.CoveredEvents);
foreach (var service in eventProjectionOptions.Services)
_services.Add(service);

foreach (var extension in _extensions)
extension(_services);
Expand Down
17 changes: 9 additions & 8 deletions src/EventSourcing/EventSourcing.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
Expand All @@ -17,7 +17,7 @@ The persistance is based on the EntityFramworkCore and can be configured via Dep
<RepositoryUrl>https://github.com/mrmorrandir/EventSourcing</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>EventSourcing, Events, EventStore</PackageTags>
<PackageVersion>1.0.0-beta-6</PackageVersion>
<PackageVersion>1.0.0-preview-20240513-0708</PackageVersion>
<PackageReleaseNotes>Breaking Changes - New Mapper Logic</PackageReleaseNotes>
</PropertyGroup>

Expand All @@ -27,15 +27,16 @@ The persistance is based on the EntityFramworkCore and can be configured via Dep

<ItemGroup>
<PackageReference Include="FluentResults" Version="3.15.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.2">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.2" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.4" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
<PackageReference Include="System.Text.Json" Version="8.0.3" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.2" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.4" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using EventSourcing.Mappers;
using EventSourcing.Projections;
using EventSourcing.Publishers.RabbitMQPublisher;
using EventSourcing.Repositories;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;

Expand All @@ -23,6 +24,7 @@ public void RegistrationShouldWork_WhenEventsAndMappersAndProjectionsAreCorrect(

var eventMappers = provider.GetRequiredService<IEnumerable<IEventMapper>>().ToArray();
var projections = provider.GetRequiredService<IEnumerable<IEventHandler>>().Select(s => (IEventHandler)s).ToList();
var eventRepository = provider.GetRequiredService<IEventRepository>();

eventMappers.Should().ContainSingle(m => m.Types.Contains("my-custom-event-v1") && m.EventType == typeof(ValidAssembly.Events.CustomEvent));
eventMappers.Should().ContainSingle(m => m.Types.Contains("default-event-v1") && m.EventType == typeof(ValidAssembly.Events.DefaultEvent));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand All @@ -11,8 +11,9 @@
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.11.0" />
<PackageReference Include="FluentResults" Version="3.15.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.2" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.4" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="xunit" Version="2.4.1" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand All @@ -10,8 +10,9 @@

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.9.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.4" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
Expand Down
Loading
Loading