Skip to content

Commit

Permalink
Update interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
pomianowski committed May 31, 2024
1 parent 047bbb2 commit faff6da
Show file tree
Hide file tree
Showing 40 changed files with 414 additions and 178 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
*.userosscache
*.sln.docstates

# Rider
.idea

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<PropertyGroup>
<Version>2.2.0</Version>
<Version>3.0.0</Version>
</PropertyGroup>

<PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/ReflectionEventing.Autofac/AutofacConsumerProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace ReflectionEventing.Autofac;
public class AutofacConsumerProvider(ILifetimeScope lifetimeScope) : IConsumerProvider
{
/// <inheritdoc />
public IEnumerable<object> GetConsumerTypes(Type consumerType)
public IEnumerable<object> GetConsumers(Type consumerType)
{
if (consumerType is null)
{
Expand Down
3 changes: 1 addition & 2 deletions src/ReflectionEventing.Autofac/ContainerBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ Action<EventBusBuilder> configure
configure(autofacBuilder);

_ = builder
.RegisterType<HashedConsumerTypesProvider>()
.RegisterInstance(autofacBuilder.BuildTypesProvider())
.As<IConsumerTypesProvider>()
.WithParameter("consumers", autofacBuilder.GetConsumers())
.SingleInstance();

_ = builder
Expand Down
2 changes: 1 addition & 1 deletion src/ReflectionEventing.Castle.Windsor/EventBusInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public void Install(IWindsorContainer container, IConfigurationStore store)
_ = container.Register(
Component
.For<IConsumerTypesProvider>()
.Instance(new HashedConsumerTypesProvider(builder.GetConsumers()))
.Instance(builder.BuildTypesProvider())
.LifestyleScoped(),
Component
.For<IConsumerProvider>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace ReflectionEventing.Castle.Windsor;
public class WindsorConsumerProvider(IWindsorContainer container) : IConsumerProvider
{
/// <inheritdoc />
public IEnumerable<object> GetConsumerTypes(Type consumerType)
public IEnumerable<object> GetConsumers(Type consumerType)
{
if (consumerType is null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace ReflectionEventing.Castle.Windsor;
public class WindsorEventBusBuilder(IWindsorContainer container) : EventBusBuilder
{
/// <inheritdoc />
public override void AddConsumer(
public override EventBusBuilder AddConsumer(
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
#endif
Expand All @@ -28,6 +28,6 @@ Type consumerType
);
}

base.AddConsumer(consumerType);
return base.AddConsumer(consumerType);
}
}
5 changes: 3 additions & 2 deletions src/ReflectionEventing.Demo.Wpf/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ public partial class App : Application

_ = services.AddEventBus(e =>
{
// _ = e.AddAllConsumers(Assembly.GetExecutingAssembly());
_ = e.AddConsumer<MainWindowViewModel>();
e.Options.UseEventPolymorphism = true;

_ = e.AddAllConsumers(Assembly.GetExecutingAssembly());
});
}
)
Expand Down
9 changes: 1 addition & 8 deletions src/ReflectionEventing.Demo.Wpf/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,4 @@
// Copyright (C) Leszek Pomianowski and ReflectionEventing Contributors.
// All Rights Reserved.

[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
3 changes: 3 additions & 0 deletions src/ReflectionEventing.Demo.Wpf/GlobalUsings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
global using System;
global using System.IO;
global using System.Linq;
global using System.Reflection;
global using System.Threading;
global using System.Threading.Tasks;
global using System.Windows;
global using CommunityToolkit.Mvvm.ComponentModel;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Hosting;
global using Microsoft.Extensions.Logging;
13 changes: 9 additions & 4 deletions src/ReflectionEventing.Demo.Wpf/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@
d:DataContext="{d:DesignInstance local:MainWindow,
IsDesignTimeCreatable=True}"
mc:Ignorable="d">
<StackPanel>
<TextBlock Text="Current tick:" />
<TextBlock Text="{Binding ViewModel.CurrentTick, Mode=OneWay}" />
</StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>

<TextBlock Grid.Column="0" Text="Current tick:" />
<TextBlock Grid.Column="1" Text="{Binding ViewModel.CurrentTick, Mode=OneWay}" />
</Grid>
</Window>
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ public async Task StartAsync(CancellationToken cancellationToken)
/// Triggered when the application host is performing a graceful shutdown.
/// </summary>
/// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>
public async Task StopAsync(CancellationToken cancellationToken)
public Task StopAsync(CancellationToken cancellationToken)
{
await Task.CompletedTask;
return Task.CompletedTask;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,12 @@ public Task StopAsync(CancellationToken cancellationToken)

private async Task TickInBackground(CancellationToken cancellationToken)
{
await eventBus.PublishAsync(new OtherEvent(), cancellationToken);

Random random = new();

while (true)
while (!cancellationToken.IsCancellationRequested)
{
if (cancellationToken.IsCancellationRequested)
{
break;
}

await eventBus.PublishAsync(
new BackgroundTicked(random.Next(10, 1001)),
cancellationToken
Expand Down
20 changes: 12 additions & 8 deletions src/ReflectionEventing.Demo.Wpf/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,37 @@
// Copyright (C) Leszek Pomianowski and ReflectionEventing Contributors.
// All Rights Reserved.

using CommunityToolkit.Mvvm.ComponentModel;
using ReflectionEventing.Demo.Wpf.Events;

namespace ReflectionEventing.Demo.Wpf.ViewModels;

public partial class MainWindowViewModel
: ObservableObject,
public partial class MainWindowViewModel(ILogger<MainWindowViewModel> logger)
: ViewModel,
IConsumer<ITickedEvent>,
IConsumer<OtherEvent>
{
[ObservableProperty]
private int _currentTick = 0;
private int _currentTick;

/// <inheritdoc />
public async Task ConsumeAsync(ITickedEvent payload, CancellationToken cancellationToken)
{
int tickValue = payload.Value;

await Application.Current.Dispatcher.InvokeAsync(() =>
{
CurrentTick = tickValue;
});
await DispatchAsync(
() =>
{
CurrentTick = tickValue;
},
cancellationToken
);
}

/// <inheritdoc />
public async Task ConsumeAsync(OtherEvent payload, CancellationToken cancellationToken)
{
logger.LogInformation("Received {Event} event.", nameof(OtherEvent));

await Task.CompletedTask;
}
}
31 changes: 31 additions & 0 deletions src/ReflectionEventing.Demo.Wpf/ViewModels/ViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// 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.

namespace ReflectionEventing.Demo.Wpf.ViewModels;

/// <summary>
/// Represents an abstract ViewModel base class that provides functionality for dispatching actions on the UI thread.
/// </summary>
/// <remarks>
/// This class extends the ObservableObject class to provide property change notification.
/// </remarks>
public abstract class ViewModel : ObservableObject
{
/// <summary>
/// Dispatches the specified action on the UI thread.
/// </summary>
/// <param name="action">The action to be dispatched.</param>
/// <param name="cancellationToken">A cancellation token that can be used to cancel the operation.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
protected static async Task DispatchAsync(Action action, CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
{
return;
}

await Application.Current.Dispatcher.InvokeAsync(action);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class DependencyInjectionConsumerProvider(IServiceProvider serviceProvide
: IConsumerProvider
{
/// <inheritdoc />
public IEnumerable<object> GetConsumerTypes(Type consumerType)
public IEnumerable<object> GetConsumers(Type consumerType)
{
if (consumerType is null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace ReflectionEventing.DependencyInjection;
public class DependencyInjectionEventBusBuilder(IServiceCollection services) : EventBusBuilder
{
/// <inheritdoc />
public override void AddConsumer(
public override EventBusBuilder AddConsumer(
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
#endif
Expand All @@ -29,6 +29,6 @@ Type consumerType
);
}

base.AddConsumer(consumerType);
return base.AddConsumer(consumerType);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ Action<EventBusBuilder> configure

configure(builder);

_ = services.AddSingleton<IConsumerTypesProvider>(
new HashedConsumerTypesProvider(builder.GetConsumers())
);
_ = services.AddSingleton(builder.BuildTypesProvider());
_ = services.AddScoped<IConsumerProvider, DependencyInjectionConsumerProvider>();
_ = services.AddScoped<IEventBus, EventBus>();

Expand Down
10 changes: 7 additions & 3 deletions src/ReflectionEventing.Ninject/EventBusModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,18 @@ public class EventBusModule(Action<NinjectEventBusBuilder> configure) : NinjectM
/// </summary>
public override void Load()
{
if (Kernel is null)
{
throw new InvalidOperationException("The kernel is not set.");
}

NinjectEventBusBuilder builder = new(Kernel);

configure(builder);

_ = Bind<IConsumerTypesProvider>()
.To<HashedConsumerTypesProvider>()
.InSingletonScope()
.WithConstructorArgument("consumers", builder.GetConsumers());
.ToConstant(builder.BuildTypesProvider())
.InSingletonScope();

_ = Bind<IConsumerProvider>().To<NinjectConsumerProvider>().InTransientScope();

Expand Down
2 changes: 1 addition & 1 deletion src/ReflectionEventing.Ninject/NinjectConsumerProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace ReflectionEventing.Ninject;
public class NinjectConsumerProvider(IKernel kernel) : IConsumerProvider
{
/// <inheritdoc />
public IEnumerable<object> GetConsumerTypes(Type consumerType)
public IEnumerable<object> GetConsumers(Type consumerType)
{
if (consumerType is null)
{
Expand Down
4 changes: 2 additions & 2 deletions src/ReflectionEventing.Ninject/NinjectEventBusBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ namespace ReflectionEventing.Ninject;
public class NinjectEventBusBuilder(IKernel kernel) : EventBusBuilder
{
/// <inheritdoc />
public override void AddConsumer(Type consumerType)
public override EventBusBuilder AddConsumer(Type consumerType)
{
if (!kernel.GetBindings(consumerType).Any())
{
throw new InvalidOperationException("Event consumer must be registered in the kernel.");
}

base.AddConsumer(consumerType);
return base.AddConsumer(consumerType);
}
}
2 changes: 1 addition & 1 deletion src/ReflectionEventing.Unity/UnityConsumerProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace ReflectionEventing.Unity;
public class UnityConsumerProvider(IUnityContainer container) : IConsumerProvider
{
/// <inheritdoc />
public IEnumerable<object> GetConsumerTypes(Type consumerType)
public IEnumerable<object> GetConsumers(Type consumerType)
{
if (consumerType is null)
{
Expand Down
6 changes: 3 additions & 3 deletions src/ReflectionEventing.Unity/UnityContainerExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ public static IUnityContainer AddEventBus(
Action<UnityEventBusBuilder> configure
)
{
UnityEventBusBuilder builder = new UnityEventBusBuilder(container);
UnityEventBusBuilder builder = new(container);

configure(builder);

_ = container.RegisterInstance<IConsumerTypesProvider>(
new HashedConsumerTypesProvider(builder.GetConsumers()),
_ = container.RegisterInstance(
builder.BuildTypesProvider(),
new ContainerControlledLifetimeManager()
);

Expand Down
38 changes: 13 additions & 25 deletions src/ReflectionEventing/EventBus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,37 +16,25 @@ public class EventBus(
IConsumerTypesProvider consumerTypesProvider
) : IEventBus
{
/// <inheritdoc />
public void Publish<TEvent>(TEvent eventItem)
{
Task.Run(() =>
{
using CancellationTokenSource cancellationSource = new();

PublishAsync(eventItem, cancellationSource.Token)
.ConfigureAwait(false)
.GetAwaiter()
.GetResult();
})
.GetAwaiter()
.GetResult();
}

/// <inheritdoc />
public async Task PublishAsync<TEvent>(TEvent eventItem, CancellationToken cancellationToken)
where TEvent : class
{
List<Task> tasks = new();
IEnumerable<Type> consumerTypes = consumerTypesProvider.GetConsumerTypes(typeof(TEvent));
if (eventItem is null)
{
throw new ArgumentNullException(nameof(eventItem));
}

Type eventType = typeof(TEvent);
List<Task> tasks = [];
IEnumerable<Type> consumerTypes = consumerTypesProvider.GetConsumerTypes(eventType);

foreach (Type consumerType in consumerTypes)
{
IEnumerable<IConsumer<TEvent>> consumerObjects = consumerProviders
.GetConsumerTypes(consumerType)
.OfType<IConsumer<TEvent>>();

tasks.AddRange(
consumerObjects.Select(x => x.ConsumeAsync(eventItem, cancellationToken))
);
foreach (object consumer in consumerProviders.GetConsumers(consumerType))
{
tasks.Add(((IConsumer<TEvent>)consumer).ConsumeAsync(eventItem, cancellationToken));
}
}

await Task.WhenAll(tasks).ConfigureAwait(false);
Expand Down
Loading

0 comments on commit faff6da

Please sign in to comment.