Skip to content

Commit

Permalink
Added event publisher methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
ShreyasJejurkar committed Oct 3, 2020
1 parent 54694ea commit c745a6b
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 14 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ obj/
riderModule.iml
/_ReSharper.Caches/
.rider/
.idea/
.idea/
/.vs/Eventify/DesignTimeBuild/.dtbcache.v2
/.vs/Eventify/v16/TestStore/0
/.vs/Eventify/v16
6 changes: 3 additions & 3 deletions src/Eventify/Event.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ namespace Eventify
public abstract class Event
{
/// <summary>
/// <see cref="DateTimeOffset"/> when given <see cref="Event"/> occured.
/// <see cref="DateTimeOffset"/> when given <see cref="Event"/> occurred.
/// </summary>
public DateTimeOffset EventOccuredAt { get; }
public DateTimeOffset EventOccurredAt { get; }

/// <summary>
/// Unique Event Id that represents an <see cref="Event"/>
Expand All @@ -20,7 +20,7 @@ public abstract class Event
protected Event()
{
EventId = Guid.NewGuid();
EventOccuredAt = DateTimeOffset.UtcNow;
EventOccurredAt = DateTimeOffset.UtcNow;
}
}
}
40 changes: 40 additions & 0 deletions src/Eventify/EventPublishedContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;

namespace Eventify
{
/// <summary>
/// Contains event information which gets passed to
/// <see cref="IEventPublisherListener.OnEventPublished"/>
/// after publishing event
/// </summary>
public class EventPublishedContext : EventPublishingContext
{
/// <summary>
/// Represents the does exception occurred while publishing event or not
/// </summary>
public bool IsFaulted => EventExceptionList.Count != 0;

/// <summary>
/// This will contain occurred exception information for further logging or processing
/// </summary>
public List<Exception> EventExceptionList { get; }

/// <summary>
/// Type of handler in which <see cref="Exception"/> has been thrown-ed
/// </summary>
public List<Type> ExceptionHandlerTypeList { get; }

internal EventPublishedContext(Guid eventId, string eventName, Type eventType) : base(eventId, eventName, eventType)
{
EventExceptionList = new List<Exception>();
ExceptionHandlerTypeList = new List<Type>();
}

internal void SetException(Exception e, Type handlerExceptionType)
{
EventExceptionList.Add(e);
ExceptionHandlerTypeList.Add(handlerExceptionType);
}
}
}
51 changes: 51 additions & 0 deletions src/Eventify/EventPublishingContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;

namespace Eventify
{
/// <summary>
/// Contains event information which gets passed to
/// <see cref="IEventPublisherListener.OnEventPublishing"/>
/// before publishing event
/// </summary>
public class EventPublishingContext
{
protected object _eventData;

/// <summary>
/// Id of currently published <see cref="Event"/>
/// </summary>
public Guid EventId { get; }

/// <summary>
/// Name of currently publishing <see cref="Event"/>
/// </summary>
public string EventName { get; }

/// <summary>
/// Type of <see cref="Event"/> class
/// </summary>
public Type EventType { get; }

internal EventPublishingContext(Guid eventId, string eventName, Type eventType)
{
EventId = eventId;
EventName = eventName;
EventType = eventType;
}

public void SetEventData<T>(T eventData)
{
_eventData = eventData;
}

public T GetEventData<T>()
{
return (T)_eventData;
}

public dynamic GetEventData()
{
return _eventData;
}
}
}
1 change: 1 addition & 0 deletions src/Eventify/Eventify.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="1.1.0" />
</ItemGroup>

Expand Down
3 changes: 1 addition & 2 deletions src/Eventify/EventifyServiceExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public static void AddEventify(this IServiceCollection services, params Assembly
{
throw new Exception("Please provide at least one assembly to scan for EventHandlers");
}

foreach (var assembly in assemblies)
{
var classTypes = assembly.GetTypes().Select(t => t.GetTypeInfo()).Where(t => t.IsClass && !t.IsAbstract);
Expand All @@ -29,7 +29,6 @@ public static void AddEventify(this IServiceCollection services, params Assembly
}
}
}

services.AddScoped<IEventPublisher, InMemoryEventPublisher>();
}
}
Expand Down
20 changes: 20 additions & 0 deletions src/Eventify/IEventPublisherListener.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace Eventify
{
/// <summary>
/// Contract for Event listeners
/// </summary>
public interface IEventPublisherListener
{
/// <summary>
/// Gets executed before publishing an <see cref="Event"/>
/// </summary>
/// <param name="context">Context containing current <see cref="Event"/> information</param>
void OnEventPublishing(EventPublishingContext context);

/// <summary>
/// Gets executed after publishing an <see cref="Event"/>
/// </summary>
/// <param name="context">Context containing event execution information</param>
void OnEventPublished(EventPublishedContext context);
}
}
54 changes: 46 additions & 8 deletions src/Eventify/InMemoryEventPublisher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,73 @@
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Eventify
{
/// <summary>
/// A event publisher that publishes event in memory
/// A event publisher that publishes event in process/memory
/// </summary>
public class InMemoryEventPublisher : IEventPublisher
{
private readonly IServiceProvider _serviceProvider;
private static readonly ConcurrentDictionary<Type, object> EventHandlers = new ConcurrentDictionary<Type, object>();
private readonly IEnumerable<IEventPublisherListener> _eventPublisherListener;
private readonly ConcurrentDictionary<Type, IEnumerable> _handlersCacheDictionary = new ConcurrentDictionary<Type, IEnumerable>();

public InMemoryEventPublisher(IServiceProvider serviceProvider)
public InMemoryEventPublisher(IServiceProvider serviceProvider, IEnumerable<IEventPublisherListener> eventPublisherListener)
{
_serviceProvider = serviceProvider;
_eventPublisherListener = eventPublisherListener;
}

public Task Publish(Event @event)
{
var eventHandlerType = typeof(IEventHandler<>).MakeGenericType(@event.GetType());

var handlers =
(IEnumerable) _serviceProvider.GetService(typeof(IEnumerable<>).MakeGenericType(eventHandlerType));
var handlers = _handlersCacheDictionary.GetOrAdd(@event.GetType(), (IEnumerable)_serviceProvider.GetService(typeof(IEnumerable<>).MakeGenericType(eventHandlerType)));

var currentEventType = @event.GetType();
var currentEventName = currentEventType.Name;

var eventPublishingContext =
new EventPublishingContext(@event.EventId, currentEventName, currentEventType);

eventPublishingContext.SetEventData(@event);

if(_eventPublisherListener != null && _eventPublisherListener.Any())
{
foreach (var listeners in _eventPublisherListener)
{
listeners.OnEventPublishing(eventPublishingContext);
}
}

EventPublishedContext publishedContext = null;

foreach (var handler in handlers)
{
handler.GetType().GetMethod("Handle")?.Invoke(handler, new object[] {@event});
publishedContext =
new EventPublishedContext(@event.EventId, currentEventName, currentEventType);
try
{
handler.GetType().GetMethod("Handle")?.Invoke(handler, new object[] {eventPublishingContext.GetEventData()});
}
catch (Exception e)
{
publishedContext.SetException(e, handler.GetType());
publishedContext.SetEventData(eventPublishingContext.GetEventData());
}
}

if (_eventPublisherListener != null && _eventPublisherListener.Any())
{
foreach (var item in _eventPublisherListener)
{
item.OnEventPublished(publishedContext);
}
}

return Task.CompletedTask;
}
}
Expand Down

0 comments on commit c745a6b

Please sign in to comment.