-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
be4c339
commit 0b96617
Showing
14 changed files
with
327 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
src/ReflectionEventing.Castle.Windsor/EventBusInstaller.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// This Source Code Form is subject to the terms of the MIT License. | ||
// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. | ||
// Copyright (C) Leszek Pomianowski and ReflectionEventing Contributors. | ||
// All Rights Reserved. | ||
|
||
using Castle.MicroKernel.Registration; | ||
using Castle.MicroKernel.SubSystems.Configuration; | ||
using Castle.Windsor; | ||
|
||
namespace ReflectionEventing.Castle.Windsor; | ||
|
||
/// <summary> | ||
/// Represents a Castle Windsor installer for configuring the event bus and its related services. | ||
/// </summary> | ||
public class EventBusInstaller(Action<WindsorEventBusBuilder> configure) : IWindsorInstaller | ||
{ | ||
/// <summary> | ||
/// Adds the event bus and its related services to the specified Windsor container. | ||
/// </summary> | ||
/// <param name="container">The <see cref="IWindsorContainer"/> to add the event bus to.</param> | ||
/// <param name="store">The <see cref="IConfigurationStore"/> for the container.</param> | ||
public void Install(IWindsorContainer container, IConfigurationStore store) | ||
{ | ||
WindsorEventBusBuilder builder = new(container); | ||
|
||
if (!container.Kernel.HasComponent(typeof(IWindsorContainer))) | ||
{ | ||
_ = container.Register(Component.For<IWindsorContainer>().Instance(container)); | ||
} | ||
|
||
configure(builder); | ||
|
||
_ = container.Register( | ||
Component | ||
.For<IConsumerTypesProvider>() | ||
.Instance(new HashedConsumerTypesProvider(builder.GetConsumers())) | ||
.LifestyleScoped(), | ||
Component | ||
.For<IConsumerProvider>() | ||
.ImplementedBy<WindsorConsumerProvider>() | ||
.LifestyleScoped(), | ||
Component.For<IEventBus>().ImplementedBy<EventBus>().LifestyleTransient() | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// This Source Code Form is subject to the terms of the MIT License. | ||
// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. | ||
// Copyright (C) Leszek Pomianowski and ReflectionEventing Contributors. | ||
// All Rights Reserved. | ||
|
||
global using System; | ||
global using System.Collections.Generic; |
42 changes: 42 additions & 0 deletions
42
src/ReflectionEventing.Castle.Windsor/ReflectionEventing.Castle.Windsor.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<PackageId>ReflectionEventing.Castle.Windsor</PackageId> | ||
<TargetFrameworks>netstandard2.0;netstandard2.1;net462;net6.0;net8.0</TargetFrameworks> | ||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> | ||
<IsTrimmable>true</IsTrimmable> | ||
<EnableTrimAnalyzer>true</EnableTrimAnalyzer> | ||
</PropertyGroup> | ||
|
||
<PropertyGroup Condition="'$(TargetFramework)' == 'net8.0'"> | ||
<PublishAot>true</PublishAot> | ||
<StripSymbols>true</StripSymbols> | ||
<OptimizationPreference>Speed</OptimizationPreference> | ||
</PropertyGroup> | ||
|
||
<!-- Necessary polyfills --> | ||
<PropertyGroup> | ||
<PolySharpIncludeGeneratedTypes> | ||
System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute; | ||
System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute; | ||
System.Diagnostics.CodeAnalysis.MemberNotNullAttribute; | ||
System.Diagnostics.CodeAnalysis.NotNullAttribute; | ||
System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute; | ||
System.Diagnostics.CodeAnalysis.NotNullWhenAttribute; | ||
System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute; | ||
System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute; | ||
System.Runtime.CompilerServices.CallerArgumentExpressionAttribute; | ||
System.Runtime.CompilerServices.IsExternalInit; | ||
System.Runtime.CompilerServices.SkipLocalsInitAttribute; | ||
</PolySharpIncludeGeneratedTypes> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Castle.Windsor" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\ReflectionEventing\ReflectionEventing.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
25 changes: 25 additions & 0 deletions
25
src/ReflectionEventing.Castle.Windsor/WindsorConsumerProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// This Source Code Form is subject to the terms of the MIT License. | ||
// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. | ||
// Copyright (C) Leszek Pomianowski and ReflectionEventing Contributors. | ||
// All Rights Reserved. | ||
|
||
using Castle.Windsor; | ||
|
||
namespace ReflectionEventing.Castle.Windsor; | ||
|
||
/// <summary> | ||
/// Represents a provider for retrieving event consumers from Castle Windsor's IoC container. | ||
/// </summary> | ||
public class WindsorConsumerProvider(IWindsorContainer container) : IConsumerProvider | ||
{ | ||
/// <inheritdoc /> | ||
public IEnumerable<object> GetConsumerTypes(Type consumerType) | ||
{ | ||
if (consumerType is null) | ||
{ | ||
throw new ArgumentNullException(nameof(consumerType)); | ||
} | ||
|
||
return container.ResolveAll(consumerType) as object[] ?? []; | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
src/ReflectionEventing.Castle.Windsor/WindsorEventBusBuilder.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// This Source Code Form is subject to the terms of the MIT License. | ||
// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. | ||
// Copyright (C) Leszek Pomianowski and ReflectionEventing Contributors. | ||
// All Rights Reserved. | ||
|
||
using System.Diagnostics.CodeAnalysis; | ||
using Castle.Windsor; | ||
|
||
namespace ReflectionEventing.Castle.Windsor; | ||
|
||
/// <summary> | ||
/// Represents a builder for configuring the event bus with Castle Windsor's IoC container. | ||
/// </summary> | ||
public class WindsorEventBusBuilder(IWindsorContainer container) : EventBusBuilder | ||
{ | ||
/// <inheritdoc /> | ||
public override void AddConsumer( | ||
#if NET5_0_OR_GREATER | ||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] | ||
#endif | ||
Type consumerType | ||
) | ||
{ | ||
if (!container.Kernel.HasComponent(consumerType)) | ||
{ | ||
throw new InvalidOperationException( | ||
"Event consumer must be registered in the container." | ||
); | ||
} | ||
|
||
base.AddConsumer(consumerType); | ||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
src/ReflectionEventing.Ninject/ReflectionEventing.Ninject.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
tests/ReflectionEventing.Castle.Windsor.UnitTests/EventBusInstallerTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// This Source Code Form is subject to the terms of the MIT License. | ||
// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. | ||
// Copyright (C) Leszek Pomianowski and ReflectionEventing Contributors. | ||
// All Rights Reserved. | ||
|
||
using Castle.MicroKernel.Lifestyle; | ||
using Castle.MicroKernel.Registration; | ||
using Castle.Windsor; | ||
|
||
namespace ReflectionEventing.Castle.Windsor.UnitTests; | ||
|
||
public sealed class EventBusInstallerTests | ||
{ | ||
[Fact] | ||
public void Install_RegistersServicesAndAddsConsumer() | ||
{ | ||
IWindsorContainer container = new WindsorContainer(); | ||
|
||
_ = container.Register(Component.For<TestConsumer>().LifestyleScoped()); | ||
|
||
EventBusInstaller installer = | ||
new(builder => | ||
{ | ||
_ = builder.AddConsumer<TestConsumer>(); | ||
}); | ||
|
||
installer.Install(container, null!); | ||
|
||
using IDisposable scope = container.BeginScope(); | ||
|
||
IConsumerTypesProvider consumerTypesProvider = container.Resolve<IConsumerTypesProvider>(); | ||
_ = consumerTypesProvider.Should().NotBeNull(); | ||
_ = consumerTypesProvider.Should().BeOfType<HashedConsumerTypesProvider>(); | ||
|
||
IConsumerProvider consumerProvider = container.Resolve<IConsumerProvider>(); | ||
_ = consumerProvider.Should().NotBeNull(); | ||
_ = consumerProvider.Should().BeOfType<WindsorConsumerProvider>(); | ||
|
||
IEventBus eventBus = container.Resolve<IEventBus>(); | ||
_ = eventBus.Should().NotBeNull(); | ||
_ = eventBus.Should().BeOfType<EventBus>(); | ||
|
||
IEnumerable<Type> consumers = consumerTypesProvider.GetConsumerTypes<TestEvent>(); | ||
|
||
_ = consumers.First().Should().Be(typeof(TestConsumer)); | ||
} | ||
|
||
public class TestConsumer : IConsumer<TestEvent> | ||
{ | ||
public Task ConsumeAsync(TestEvent payload, CancellationToken cancellationToken) => | ||
Task.CompletedTask; | ||
} | ||
|
||
public sealed record TestEvent; | ||
} |
59 changes: 59 additions & 0 deletions
59
tests/ReflectionEventing.Castle.Windsor.UnitTests/EventBusTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// This Source Code Form is subject to the terms of the MIT License. | ||
// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. | ||
// Copyright (C) Leszek Pomianowski and ReflectionEventing Contributors. | ||
// All Rights Reserved. | ||
|
||
using Castle.MicroKernel.Lifestyle; | ||
using Castle.MicroKernel.Registration; | ||
using Castle.Windsor; | ||
|
||
namespace ReflectionEventing.Castle.Windsor.UnitTests; | ||
|
||
public sealed class EventBusTests : IDisposable | ||
{ | ||
private readonly IWindsorContainer _container; | ||
|
||
public EventBusTests() | ||
{ | ||
_container = new WindsorContainer(); | ||
_ = _container.Register(Component.For<TestConsumer>().LifestyleScoped()); | ||
|
||
EventBusInstaller installer = | ||
new(builder => | ||
{ | ||
_ = builder.AddConsumer<TestConsumer>(); | ||
}); | ||
|
||
installer.Install(_container, null!); | ||
} | ||
|
||
[Fact] | ||
public async Task PublishAsync_ShouldCallConsumeAsyncOnAllConsumers() | ||
{ | ||
using IDisposable scope = _container.BeginScope(); | ||
IEventBus eventBus = _container.Resolve<IEventBus>(); | ||
|
||
await eventBus.PublishAsync(new TestEvent(), CancellationToken.None); | ||
|
||
_ = _container.Resolve<TestConsumer>().ReceivedEvents.Should().Be(1); | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
_container.Dispose(); | ||
} | ||
|
||
public class TestConsumer : IConsumer<TestEvent> | ||
{ | ||
public int ReceivedEvents { get; private set; } = 0; | ||
|
||
public Task ConsumeAsync(TestEvent payload, CancellationToken cancellationToken) | ||
{ | ||
ReceivedEvents++; | ||
|
||
return Task.CompletedTask; | ||
} | ||
} | ||
|
||
public sealed record TestEvent; | ||
} |
12 changes: 12 additions & 0 deletions
12
tests/ReflectionEventing.Castle.Windsor.UnitTests/GlobalUsings.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// This Source Code Form is subject to the terms of the MIT License. | ||
// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. | ||
// Copyright (C) Leszek Pomianowski and ReflectionEventing Contributors. | ||
// All Rights Reserved. | ||
|
||
global using System; | ||
global using System.Collections.Generic; | ||
global using System.Linq; | ||
global using System.Threading; | ||
global using System.Threading.Tasks; | ||
global using FluentAssertions; | ||
global using Xunit; |
28 changes: 28 additions & 0 deletions
28
...ctionEventing.Castle.Windsor.UnitTests/ReflectionEventing.Castle.Windsor.UnitTests.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<IsPackable>false</IsPackable> | ||
<IsTestProject>true</IsTestProject> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="FluentAssertions"/> | ||
<PackageReference Include="NSubstitute"/> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk"/> | ||
<PackageReference Include="xunit" /> | ||
<PackageReference Include="xunit.runner.visualstudio"> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
<PrivateAssets>all</PrivateAssets> | ||
</PackageReference> | ||
<PackageReference Include="coverlet.collector"> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
<PrivateAssets>all</PrivateAssets> | ||
</PackageReference> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\src\ReflectionEventing.Castle.Windsor\ReflectionEventing.Castle.Windsor.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |