Skip to content

Commit

Permalink
refactor handler descriptors
Browse files Browse the repository at this point in the history
  • Loading branch information
litenova committed Dec 8, 2023
1 parent fe7a191 commit 2b0622c
Show file tree
Hide file tree
Showing 33 changed files with 191 additions and 212 deletions.
8 changes: 0 additions & 8 deletions src/LiteBus.Messaging.Abstractions/Descriptors/IDescriptor.cs

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

namespace LiteBus.Messaging.Abstractions;

public interface ILazyHandlerCollection<THandler, TDescriptor> : IReadOnlyCollection<LazyHandler<THandler, TDescriptor>>
public interface ILazyHandlerCollection<THandler, TDescriptor> : IReadOnlyCollection<LazyHandler<THandler, TDescriptor>> where TDescriptor : IHandlerDescriptor
{
}
4 changes: 2 additions & 2 deletions src/LiteBus.Messaging.Abstractions/IMessageDependencies.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ public interface IMessageDependencies
/// <value>
/// The collection of direct message handlers.
/// </value>
ILazyHandlerCollection<IMessageHandler, IHandlerDescriptor> Handlers { get; }
ILazyHandlerCollection<IMessageHandler, IMainHandlerDescriptor> Handlers { get; }

/// <summary>
/// Gets a lazy initialized read-only collection of indirect message handlers. These handlers can be used to handle messages in a more general manner, potentially handling a variety of different message types or performing logging or other cross-cutting concerns.
/// </summary>
/// <value>
/// The collection of indirect message handlers.
/// </value>
ILazyHandlerCollection<IMessageHandler, IHandlerDescriptor> IndirectHandlers { get; }
ILazyHandlerCollection<IMessageHandler, IMainHandlerDescriptor> IndirectHandlers { get; }

/// <summary>
/// Gets a lazy initialized read-only collection of direct pre-message handlers. These handlers are invoked before the primary message handlers and can be used for tasks such as validation or logging.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=mainhandle/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=mediationstrategies/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=posthandle/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=prehandle/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=prehandle/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=registry/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=registry_005Cdescriptors/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace LiteBus.Messaging.Abstractions;

/// <summary>
/// Represents a descriptor for an error handler, providing metadata about the handler such as the message type it handles,
/// its execution order, and any associated tags.
/// </summary>
public interface IErrorHandlerDescriptor : IHandlerDescriptor
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;

namespace LiteBus.Messaging.Abstractions;

/// <summary>
/// Represents a descriptor for a handler, providing metadata about the handler such as the message type it handles,
/// its execution order, and any associated tags.
/// </summary>
public interface IHandlerDescriptor
{
/// <summary>
/// Gets the type of the message that the handler is associated with. If the message type is generic,
/// this property returns the generic type definition.
/// </summary>
Type MessageType { get; }

/// <summary>
/// Gets the order in which the handler should be executed. Handlers with lower order values are executed first.
/// </summary>
int Order { get; }

/// <summary>
/// Gets a collection of tags associated with the handler. Tags can be used to categorize or identify handlers in a flexible way.
/// </summary>
IReadOnlyCollection<string> Tags { get; }

/// <summary>
/// Gets the type of the handler. This represents the actual implementation type of the handler.
/// </summary>
Type HandlerType { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;

namespace LiteBus.Messaging.Abstractions;

/// <summary>
/// Represents a descriptor for a main handler, providing metadata about the handler such as the message type it handles,
/// its execution order, any associated tags, and the type of the result produced by the handler.
/// </summary>
public interface IMainHandlerDescriptor : IHandlerDescriptor
{
/// <summary>
/// Gets the type of the result produced by the main handler.
/// </summary>
Type MessageResultType { get; }
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;

namespace LiteBus.Messaging.Abstractions;

public interface IMessageDescriptor : IDescriptor
public interface IMessageDescriptor
{
Type MessageType { get; }

bool IsGeneric { get; }

IReadOnlyCollection<IHandlerDescriptor> Handlers { get; }
IReadOnlyCollection<IMainHandlerDescriptor> Handlers { get; }

IReadOnlyCollection<IHandlerDescriptor> IndirectHandlers { get; }
IReadOnlyCollection<IMainHandlerDescriptor> IndirectHandlers { get; }

IReadOnlyCollection<IPostHandlerDescriptor> PostHandlers { get; }

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;

namespace LiteBus.Messaging.Abstractions;

/// <summary>
/// Represents a descriptor for a post-handler, providing metadata about the handler such as the message type it handles,
/// its execution order, any associated tags, and the type of the result that is expected by the user as an argument.
/// </summary>
public interface IPostHandlerDescriptor : IHandlerDescriptor
{
/// <summary>
/// Gets the type of the result produced by the main handler that is associated with this post-handler.
/// </summary>
Type MessageResultType { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace LiteBus.Messaging.Abstractions;

/// <summary>
/// Represents a descriptor for a pre-handler, providing metadata about the handler such as the message type it handles,
/// its execution order, and any associated tags.
/// </summary>
public interface IPreHandlerDescriptor : IHandlerDescriptor
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,17 +63,17 @@ public void Initialize()

foreach (var postHandleDescriptor in descriptor.PostHandlers.Concat(descriptor.IndirectPostHandlers))
{
_services.TryAddTransient(postHandleDescriptor.PostHandlerType);
_services.TryAddTransient(postHandleDescriptor.HandlerType);
}

foreach (var preHandleDescriptor in descriptor.PreHandlers.Concat(descriptor.IndirectPreHandlers))
{
_services.TryAddTransient(preHandleDescriptor.PreHandlerType);
_services.TryAddTransient(preHandleDescriptor.HandlerType);
}

foreach (var errorHandlerDescriptor in descriptor.ErrorHandlers.Concat(descriptor.IndirectErrorHandlers))
{
_services.TryAddTransient(errorHandlerDescriptor.ErrorHandlerType);
_services.TryAddTransient(errorHandlerDescriptor.HandlerType);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace LiteBus.Messaging.Internal.Extensions;
public static class EnumerableExtensions
{
public static ILazyHandlerCollection<THandler, TDescriptor> ToLazyReadOnlyCollection<THandler, TDescriptor>(this IEnumerable<LazyHandler<THandler, TDescriptor>> source)
where TDescriptor : IHandlerDescriptor
{
return new LazyHandlerCollection<THandler, TDescriptor>(source);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace LiteBus.Messaging.Internal;

public sealed class LazyHandlerCollection<THandler, TDescriptor> : ILazyHandlerCollection<THandler, TDescriptor>
public sealed class LazyHandlerCollection<THandler, TDescriptor> : ILazyHandlerCollection<THandler, TDescriptor> where TDescriptor : IHandlerDescriptor
{
private readonly List<LazyHandler<THandler, TDescriptor>> _list;

Expand Down
27 changes: 7 additions & 20 deletions src/LiteBus.Messaging/Internal/Mediator/MessageDependencies.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ public MessageDependencies(Type messageType, IMessageDescriptor descriptor, ISer
IndirectErrorHandlers = ResolveHandlers(descriptor.IndirectErrorHandlers, (handlerType) => (IMessageErrorHandler) serviceProvider.GetService(handlerType));
}

public ILazyHandlerCollection<IMessageHandler, IHandlerDescriptor> Handlers { get; }
public ILazyHandlerCollection<IMessageHandler, IMainHandlerDescriptor> Handlers { get; }

public ILazyHandlerCollection<IMessageHandler, IHandlerDescriptor> IndirectHandlers { get; }
public ILazyHandlerCollection<IMessageHandler, IMainHandlerDescriptor> IndirectHandlers { get; }

public ILazyHandlerCollection<IMessagePreHandler, IPreHandlerDescriptor> PreHandlers { get; }

Expand All @@ -49,10 +49,10 @@ public MessageDependencies(Type messageType, IMessageDescriptor descriptor, ISer
/// </summary>
private ILazyHandlerCollection<THandler, TDescriptor> ResolveHandlers<THandler, TDescriptor>(
IEnumerable<TDescriptor> descriptors,
Func<Type, THandler> resolveFunc)
Func<Type, THandler> resolveFunc) where TDescriptor : IHandlerDescriptor
{
return descriptors
.OrderBy(d => GetOrder(d))
.OrderBy(d => d.Order)
.Select(d => new LazyHandler<THandler, TDescriptor>
{
Handler = new Lazy<THandler>(() => resolveFunc(GetHandlerType(d))),
Expand All @@ -61,27 +61,14 @@ public MessageDependencies(Type messageType, IMessageDescriptor descriptor, ISer
.ToLazyReadOnlyCollection();
}

/// <summary>
/// Retrieves the order value from a descriptor.
/// </summary>
private static int GetOrder(object descriptor)
{
return (int) descriptor.GetType().GetProperty("Order").GetValue(descriptor);
}

/// <summary>
/// Retrieves the handler type from a descriptor, adjusting for generic types as necessary.
/// </summary>
private Type GetHandlerType(object descriptor)
private Type GetHandlerType(IHandlerDescriptor descriptor)
{
var handlerTypeProp = descriptor.GetType().GetProperty("HandlerType") ??
descriptor.GetType().GetProperty($"{descriptor.GetType().Name.Replace("Descriptor", string.Empty)}Type");

var isGenericProp = descriptor.GetType().GetProperty("IsGeneric");

var handlerType = (Type) handlerTypeProp.GetValue(descriptor);
var handlerType = descriptor.HandlerType;

if ((bool) isGenericProp.GetValue(descriptor))
if (descriptor.MessageType.IsGenericType)
{
handlerType = handlerType.MakeGenericType(_messageType.GetGenericArguments());
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

namespace LiteBus.Messaging.Internal.Registry.Abstractions;

internal interface IDescriptorBuilder
internal interface IHandlerDescriptorBuilder
{
bool CanBuild(Type type);

IEnumerable<IDescriptor> Build(Type type);
IEnumerable<IHandlerDescriptor> Build(Type type);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,31 @@

namespace LiteBus.Messaging.Internal.Registry.Builders;

internal sealed class ErrorHandlerDescriptorBuilder : IDescriptorBuilder<IErrorHandlerDescriptor>
internal sealed class ErrorHandlerDescriptorBuilder : IHandlerDescriptorBuilder
{
public bool CanBuild(Type type)
{
return type.IsAssignableTo(typeof(IMessageErrorHandler));
}

public IEnumerable<IErrorHandlerDescriptor> Build(Type handlerType)
public IEnumerable<IHandlerDescriptor> Build(Type handlerType)
{
var interfaces = handlerType.GetInterfacesEqualTo(typeof(IMessageErrorHandler<,>));
var order = handlerType.GetOrderFromAttribute();

foreach (var @interface in interfaces)
{
var messageType = @interface.GetGenericArguments()[0];
yield return new ErrorHandlerDescriptor(handlerType, messageType, order);
var messageResultType = @interface.GetGenericArguments()[1];

yield return new ErrorHandlerDescriptor
{
MessageType = messageType.IsGenericType ? messageType.GetGenericTypeDefinition() : messageType,
MessageResultType = messageResultType,
Order = order,
Tags = ArraySegment<string>.Empty,
HandlerType = handlerType,
};
}
}
}
Loading

0 comments on commit 2b0622c

Please sign in to comment.