Skip to content

Commit e427d33

Browse files
Add project files.
1 parent a43fc51 commit e427d33

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1796
-0
lines changed

Assets/Eventor.snk

596 Bytes
Binary file not shown.

Assets/eventor-icon.png

3.88 KB
Loading
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using Eventor.ConsoleDemo.Common.Events;
2+
using Eventor.Core.Common.Seeds;
3+
4+
namespace Eventor.ConsoleDemo.Common.DynamicEventHandlers;
5+
6+
public class AnotherBasicEventHandler : IEventHandler<AnotherBasicEvent>
7+
{
8+
public async Task Handle(AnotherBasicEvent theEvent, CancellationToken cancellationToken)
9+
{
10+
await Console.Out.WriteLineAsync($"Handling the event {nameof(AnotherBasicEvent)} in the dynamic event handler: {nameof(AnotherBasicEventHandler)}\r\n");
11+
}
12+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using Eventor.ConsoleDemo.Common.Events;
2+
using Eventor.Core.Common.Seeds;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
9+
namespace Eventor.ConsoleDemo.Common.DynamicEventHandlers
10+
{
11+
public class OrderProcessedEventHandler : IEventHandler<OrderProcessedEvent>
12+
{
13+
public async Task Handle(OrderProcessedEvent theEvent, CancellationToken cancellationToken)
14+
{
15+
await Console.Out.WriteLineAsync($"Handling the event {nameof(OrderProcessedEvent)} for order: {theEvent.OrderID}\r\n in the dynamic event handler: {nameof(OrderProcessedEventHandler)}\r\n");
16+
}
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using Eventor.ConsoleDemo.Common.Events;
2+
using Eventor.Core.Common.Seeds;
3+
4+
namespace Eventor.ConsoleDemo.Common.DynamicEventHandlers;
5+
6+
public class YetAnotherBasicEventHandlerThatThrowsExceptions : IEventHandler<YetAnotherBasicEvent>
7+
{
8+
public async Task Handle(YetAnotherBasicEvent theEvent, CancellationToken cancellationToken)
9+
{
10+
await Console.Out.WriteLineAsync($"Inside the dynamic event handler: {nameof(YetAnotherBasicEventHandlerThatThrowsExceptions)} and throwing exceptions.");
11+
throw new NotImplementedException();
12+
}
13+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using Eventor.Core.Common.Seeds;
2+
using Eventor.Core.Strategies;
3+
4+
namespace Eventor.ConsoleDemo.Common.EventPublishers;
5+
public class CustomPublishingStategy : IEventPublisher
6+
{
7+
public async Task Publish<TEvent>(TEvent theEvent, List<TheEventHandler<TEvent>> handlers, CancellationToken cancellationToken = default) where TEvent : EventBase
8+
{
9+
List<Exception> exceptions = new();
10+
11+
foreach (var handler in handlers)
12+
{
13+
try
14+
{
15+
await Console.Out.WriteLineAsync($"In the custom event publisher that processes handlers one by one in sequence.");
16+
await Task.Run(() => handler(theEvent, cancellationToken));
17+
}
18+
catch (Exception ex) { exceptions.Add(ex); }
19+
}
20+
21+
if (exceptions.Any()) throw new AggregateException(exceptions);
22+
}
23+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Eventor.Core.Common.Seeds;
2+
3+
namespace Eventor.ConsoleDemo.Common.Events;
4+
5+
public class BasicEvent(string senderName) : EventBase(senderName) { };
6+
public class AnotherBasicEvent(string senderName) : EventBase(senderName) { };
7+
public class YetAnotherBasicEvent(string senderName) : EventBase(senderName) { };
8+
9+
public class CustomPublisherEvent(string senderName) : EventBase(senderName) { };
10+
11+
public class OrderProcessedEvent : EventBase
12+
{
13+
public Guid OrderID { get;}
14+
public OrderProcessedEvent(string senderName, Guid orderID) : base(senderName)
15+
{
16+
OrderID = orderID;
17+
}
18+
}
19+
20+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Autofac" Version="7.1.0" />
12+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
13+
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
14+
</ItemGroup>
15+
16+
<ItemGroup>
17+
<ProjectReference Include="..\..\Source\Eventor.Core\Eventor.Core.csproj" />
18+
</ItemGroup>
19+
20+
<ItemGroup>
21+
<Folder Include="Common\Models\" />
22+
</ItemGroup>
23+
24+
</Project>

Demos/Eventor.ConsoleDemo/Program.cs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
using Autofac;
2+
using Eventor.ConsoleDemo.Common.DynamicEventHandlers;
3+
using Eventor.ConsoleDemo.Common.EventPublishers;
4+
using Eventor.ConsoleDemo.Common.Events;
5+
using Eventor.ConsoleDemo.Scenarios;
6+
using Eventor.Core;
7+
using Eventor.Core.Common.Seeds;
8+
using Eventor.Core.Strategies;
9+
using Microsoft.Extensions.DependencyInjection;
10+
using Microsoft.Extensions.Hosting;
11+
12+
namespace Eventor.ConsoleDemo;
13+
14+
internal class Program
15+
{
16+
static async Task Main(string[] args)
17+
{
18+
19+
try
20+
{
21+
var serviceProvider = FromConfiuredMicrosoftContainer();
22+
var eventAggregator = serviceProvider.GetRequiredService<IEventAggregator>();
23+
var customEventPublisherScenario = serviceProvider.GetRequiredService<CustomEventPublisher>();
24+
/*
25+
* Or for Autofac, comment out above and uncomment below.
26+
*/
27+
//var serviceProvider = FromConfiguredAutofacContainer();
28+
//var eventAggregator = serviceProvider.Resolve<IEventAggregator>();
29+
//var customEventPublisherScenario = serviceProvider.Resolve<CustomEventPublisher>();
30+
31+
var lineSeperator = new String('-', 100) + "\r\n";
32+
33+
await Console.Out.WriteLineAsync("Running local event handlers using fire and forget and wait for all publishing methods");
34+
await Console.Out.WriteLineAsync(lineSeperator);
35+
36+
var localEventHandlers = new LocalEventHandlers(eventAggregator);
37+
38+
await localEventHandlers.RunFireAndForget();
39+
await localEventHandlers.RunFireAndForgetWithUnhandledExceptions();
40+
await localEventHandlers.RunWaitForAll();
41+
await localEventHandlers.RunWaitForAllWithUnhandledExceptions();
42+
43+
await Console.Out.WriteLineAsync("Running dynamic event handlers using fire and forget and wait for all publishing methods");
44+
await Console.Out.WriteLineAsync("They work exactly the same as the local handlers except that you cannot unsubscribe as they are dynamic/reactive");
45+
await Console.Out.WriteLineAsync(lineSeperator);
46+
47+
var dynamicEventHandlers = new DynamicEventHandlers(eventAggregator);
48+
49+
await dynamicEventHandlers.RunFireAndForget();
50+
await dynamicEventHandlers.RunWaitForAllWithUnhandledExceptions();
51+
52+
await Console.Out.WriteLineAsync("Running both handler types using fire and forget");
53+
await Console.Out.WriteLineAsync(lineSeperator);
54+
55+
await new BothHandlerTypes(eventAggregator).RunHandlersUsingFireAndForget();
56+
57+
//Give the fire and forget time to finish otherswise the console messages will get muddled.
58+
await Task.Delay(10);
59+
60+
await Console.Out.WriteLineAsync("Using a custom publisher injected in to the scenario");
61+
await Console.Out.WriteLineAsync(lineSeperator);
62+
63+
var subscription = eventAggregator.Subscribe<CustomPublisherEvent>(LocalCustomPublisherEvenHandler);
64+
await customEventPublisherScenario.RunCustomEventPublisher();
65+
66+
async Task LocalCustomPublisherEvenHandler(CustomPublisherEvent theEvent, CancellationToken cancellationToken)
67+
{
68+
await Console.Out.WriteLineAsync($"Handled the event {nameof(CustomPublisherEvent)} in the local handler {nameof(LocalCustomPublisherEvenHandler)}.");
69+
}
70+
}
71+
72+
catch (Exception ex)
73+
{
74+
await Console.Out.WriteLineAsync(ex.Message);
75+
}
76+
77+
Console.ReadLine();
78+
}
79+
80+
private static ServiceProvider FromConfiuredMicrosoftContainer()
81+
{
82+
var serviceProvider = Host.CreateApplicationBuilder()
83+
.Services
84+
.AddTransient<CustomEventPublisher>()
85+
.AddSingleton<IEventPublisher,CustomPublishingStategy>()
86+
.AddTransient<IEventHandler<AnotherBasicEvent>, AnotherBasicEventHandler>()
87+
.AddTransient<IEventHandler<YetAnotherBasicEvent>, YetAnotherBasicEventHandlerThatThrowsExceptions>()
88+
.AddTransient<IEventHandler<OrderProcessedEvent>, OrderProcessedEventHandler>()
89+
.AddSingleton<IEventAggregator>(provider => new EventAggregator(type => provider.GetRequiredService(type)))
90+
.BuildServiceProvider();
91+
92+
return serviceProvider;
93+
}
94+
95+
private static IContainer FromConfiguredAutofacContainer()
96+
{
97+
var builder = new ContainerBuilder();
98+
99+
builder.RegisterType<CustomEventPublisher>().AsSelf().InstancePerDependency();
100+
builder.RegisterType<CustomPublishingStategy>().As<IEventPublisher>().SingleInstance();
101+
builder.RegisterType<AnotherBasicEventHandler>().As<IEventHandler<AnotherBasicEvent>>().InstancePerDependency();
102+
builder.RegisterType<YetAnotherBasicEventHandlerThatThrowsExceptions>().As<IEventHandler<YetAnotherBasicEvent>>().InstancePerDependency();
103+
builder.RegisterType<OrderProcessedEventHandler>().As<IEventHandler<OrderProcessedEvent>>().InstancePerDependency();
104+
builder.Register(c =>
105+
{
106+
var context = c.Resolve<IComponentContext>();
107+
return new EventAggregator(type => context.Resolve(type));
108+
}).As<IEventAggregator>().SingleInstance();
109+
110+
return builder.Build();
111+
112+
}
113+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using Eventor.ConsoleDemo.Common.Events;
2+
using Eventor.Core.Common.Seeds;
3+
4+
namespace Eventor.ConsoleDemo.Scenarios
5+
{
6+
public class BothHandlerTypes
7+
{
8+
private readonly IEventAggregator _eventAggregator;
9+
public BothHandlerTypes(IEventAggregator eventAggregator)
10+
11+
=> _eventAggregator = eventAggregator;
12+
13+
public async Task RunHandlersUsingFireAndForget()
14+
{
15+
var orderProcessedEvent = new OrderProcessedEvent(nameof(RunHandlersUsingFireAndForget), Guid.NewGuid());
16+
var orderSubsciption = _eventAggregator.Subscribe<OrderProcessedEvent>(LocalOrderHandler);
17+
18+
await Console.Out.WriteLineAsync($"Publishing the event {nameof(OrderProcessedEvent)}.\r\n");
19+
await _eventAggregator.Publish(orderProcessedEvent);
20+
}
21+
22+
public async Task LocalOrderHandler(OrderProcessedEvent theEvent, CancellationToken cancellationToken)
23+
{
24+
await Console.Out.WriteLineAsync($"Handling the event {nameof(OrderProcessedEvent)} for order: {theEvent.OrderID}\r\n in the local event handler: {nameof(LocalOrderHandler)}\r\n");
25+
}
26+
}
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using Eventor.ConsoleDemo.Common.Events;
2+
using Eventor.Core.Common.Seeds;
3+
using Eventor.Core.Strategies;
4+
5+
namespace Eventor.ConsoleDemo.Scenarios
6+
{
7+
public class CustomEventPublisher
8+
{
9+
private readonly IEventAggregator _eventAggregator;
10+
private readonly IEventPublisher _eventPublisher;
11+
public CustomEventPublisher(IEventAggregator eventAggregator, IEventPublisher eventPublisher)
12+
13+
=> (_eventAggregator, _eventPublisher) = (eventAggregator,eventPublisher);
14+
15+
public async Task RunCustomEventPublisher()
16+
{
17+
var customPublsiherEvent = new CustomPublisherEvent(nameof(RunCustomEventPublisher));
18+
19+
await _eventAggregator.Publish(customPublsiherEvent,_eventPublisher);
20+
21+
}
22+
23+
24+
25+
26+
}
27+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using Eventor.ConsoleDemo.Common.Events;
2+
using Eventor.Core.Common.Seeds;
3+
4+
namespace Eventor.ConsoleDemo.Scenarios;
5+
6+
public class DynamicEventHandlers
7+
{
8+
private readonly IEventAggregator _eventAggregator;
9+
10+
public DynamicEventHandlers(IEventAggregator eventAggregator)
11+
12+
=> _eventAggregator = eventAggregator;
13+
14+
public async Task RunFireAndForget()
15+
{
16+
var anotherBasicEvent = new AnotherBasicEvent(nameof(RunFireAndForget));
17+
18+
await Console.Out.WriteLineAsync($"Publishing the event {nameof(AnotherBasicEvent)}.");
19+
20+
await _eventAggregator.Publish(anotherBasicEvent, PublishMethod.FireAndForget);
21+
22+
await Console.Out.WriteLineAsync($"Pausing for 10ms as otherwise the method will have completed before the dynamic handler is called as its fire and forget.");
23+
24+
await Task.Delay(10);
25+
}
26+
27+
public async Task RunWaitForAllWithUnhandledExceptions()
28+
{
29+
var yetAnotherBasicEvent = new YetAnotherBasicEvent(nameof(RunWaitForAllWithUnhandledExceptions));
30+
31+
Exception? caughtException = null;
32+
33+
try
34+
{
35+
await Console.Out.WriteLineAsync($"Publishing the event {nameof(AnotherBasicEvent)} inside a try catch block, with an exception variable that is null.");
36+
37+
await _eventAggregator.Publish(yetAnotherBasicEvent, PublishMethod.WaitForAll);
38+
}
39+
catch (Exception ex) { caughtException = ex; }
40+
41+
await Console.Out.WriteLineAsync($"Finished processing, is the exception variable still null [{caughtException is null}] - captured type: [{caughtException?.GetType().FullName}]. \r\n");
42+
43+
}
44+
45+
}

0 commit comments

Comments
 (0)