Skip to content

Commit

Permalink
New attributes for "compound" handlers. Closes GH-172
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeremy D. Miller authored and Jeremy D. Miller committed Feb 13, 2023
1 parent 3a9fbd5 commit 0f7f0f5
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<NoWarn>1570;1571;1572;1573;1574;1587;1591;1701;1702;1711;1735;0618</NoWarn>
<ImplicitUsings>true</ImplicitUsings>
<Version>0.9.8</Version>
<Version>0.9.9</Version>

<RepositoryUrl>$(PackageProjectUrl)</RepositoryUrl>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
Expand Down
35 changes: 35 additions & 0 deletions src/Testing/CoreTests/Acceptance/executing_with_middleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,18 @@ public async Task using_finally_only_middleware_sad_path()

list.Last().ShouldBe("Called Finally");
}

[Fact]
public async Task use_attributes_to_explicitly_opt_into_implied_middleware()
{
var list = await invokeMessage(new JumpBall("Go!"), _ => { });

list.ShouldHaveTheSameElementsAs(
"line up",
"Jump Ball",
"Back on Defense"
);
}
}

public class SimpleBeforeAndAfter
Expand Down Expand Up @@ -568,4 +580,27 @@ public void Handle(StrikeoutsMessage message, Recorder recorder)
{
recorder.Actions.Add($"{nameof(StrikeoutsMessage)}: {message.Pitcher}");
}
}

public record JumpBall(string Name);

public class BasketballHandler
{
[WolverineBefore]
public static void LineUp(Recorder recorder)
{
recorder.Actions.Add("line up");
}

public static void Handle(JumpBall command, Recorder recorder)
{
recorder.Actions.Add("Jump Ball");
}

[WolverineAfter]
public static void BackOnDefense(Recorder recorder)
{
recorder.Actions.Add("Back on Defense");
}

}
32 changes: 32 additions & 0 deletions src/Wolverine/Attributes/HandlerMethodAttributes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace Wolverine.Attributes;

/// <summary>
/// Marks a method on middleware types or handler types as a method
/// that should be called before the actual handler
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class WolverineBeforeAttribute : Attribute
{

}

/// <summary>
/// Marks a method on middleware types or handler types as a method
/// that should be called after the actual handler
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class WolverineAfterAttribute : Attribute
{

}

/// <summary>
/// Marks a method on middleware types or handler types as a method
/// that should be called after the actual handler in the finally block of
/// a try/finally block around the message handlers
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class WolverineFinallyAttribute : Attribute
{

}
10 changes: 6 additions & 4 deletions src/Wolverine/Configuration/Chain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,16 +113,18 @@ protected void applyImpliedMiddlewareFromHandlers()
var handlerTypes = HandlerCalls().Select(x => x.HandlerType).Distinct();
foreach (var handlerType in handlerTypes)
{
var befores = handlerType.GetMethods().Where(x =>
MiddlewarePolicy.BeforeMethodNames.Contains(x.Name) && !x.HasAttribute<WolverineIgnoreAttribute>());
var befores = MiddlewarePolicy.FilterMethods<WolverineBeforeAttribute>(handlerType.GetMethods(),
MiddlewarePolicy.BeforeMethodNames);

foreach (var before in befores)
{
var frame = new MethodCall(handlerType, before);
Middleware.Add(frame);
}

var afters = MiddlewarePolicy.FilterMethods<WolverineAfterAttribute>(handlerType.GetMethods(),
MiddlewarePolicy.AfterMethodNames);

var afters = handlerType.GetMethods().Where(x =>
MiddlewarePolicy.AfterMethodNames.Contains(x.Name) && !x.HasAttribute<WolverineIgnoreAttribute>());
foreach (var after in afters)
{
var frame = new MethodCall(handlerType, after);
Expand Down
15 changes: 12 additions & 3 deletions src/Wolverine/Middleware/MiddlewarePolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using JasperFx.CodeGeneration.Frames;
using JasperFx.Core.Reflection;
using Lamar;
using Wolverine.Attributes;
using Wolverine.Configuration;
using Wolverine.Runtime.Handlers;

Expand Down Expand Up @@ -49,6 +50,14 @@ public Application AddType(Type middlewareType, Func<IChain, bool>? filter = nul
return application;
}

public static IEnumerable<MethodInfo> FilterMethods<T>(IEnumerable<MethodInfo> methods, string[] validNames)
where T : Attribute
{
return methods
.Where(x => !x.HasAttribute<WolverineIgnoreAttribute>())
.Where(x => validNames.Contains(x.Name) || x.HasAttribute<T>());
}

public class Application
{
private readonly MethodInfo[] _afters;
Expand Down Expand Up @@ -79,9 +88,9 @@ public Application(Type middlewareType, Func<IChain, bool> filter)

var methods = middlewareType.GetMethods().ToArray();

_befores = methods.Where(x => BeforeMethodNames.Contains(x.Name)).ToArray();
_afters = methods.Where(x => AfterMethodNames.Contains(x.Name)).ToArray();
_finals = methods.Where(x => FinallyMethodNames.Contains(x.Name)).ToArray();
_befores = FilterMethods<WolverineBeforeAttribute>(methods, BeforeMethodNames).ToArray();
_afters = FilterMethods<WolverineAfterAttribute>(methods, AfterMethodNames).ToArray();
_finals = FilterMethods<WolverineFinallyAttribute>(methods, FinallyMethodNames).ToArray();

if (!_befores.Any() && !_afters.Any() && !_finals.Any())
{
Expand Down

0 comments on commit 0f7f0f5

Please sign in to comment.