Skip to content

Commit 4a00976

Browse files
committed
Fix OnMethodEndAsync and OnEngineCompleteAsync are called in reverse.
1 parent dc72fdc commit 4a00976

File tree

7 files changed

+127
-20
lines changed

7 files changed

+127
-20
lines changed

src/ConsoleAppFramework.WebHosting/ConsoleAppFrameworkHostingExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public void Configure(IApplicationBuilder app, IHostApplicationLifetime lifetime
8888
{
8989
try
9090
{
91-
await interceptor.OnMethodEndAsync();
91+
await interceptor.OnEngineCompleteAsync(provider, logger);
9292
}
9393
catch { }
9494
});

src/ConsoleAppFramework.WebHosting/ConsoleAppFrameworkMiddleware.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,22 @@ public ValueTask OnEngineBeginAsync(IServiceProvider serviceProvider, ILogger<Co
2727
return innerInterceptor.OnEngineBeginAsync(serviceProvider, logger);
2828
}
2929

30-
public ValueTask OnMethodEndAsync()
30+
public ValueTask OnMethodEndAsync(ConsoleAppContext context, string? errorMessageIfFailed, Exception? exceptionIfExists)
3131
{
32-
return innerInterceptor.OnMethodEndAsync();
32+
this.CompleteSuccessfully = (errorMessageIfFailed == null && exceptionIfExists == null);
33+
this.ErrorMessage = errorMessageIfFailed;
34+
this.Exception = exceptionIfExists;
35+
return innerInterceptor.OnMethodEndAsync(context, errorMessageIfFailed, exceptionIfExists);
3336
}
3437

3538
public ValueTask OnMethodBeginAsync(ConsoleAppContext context)
3639
{
3740
return innerInterceptor.OnMethodBeginAsync(context);
3841
}
3942

40-
public ValueTask OnEngineCompleteAsync(ConsoleAppContext context, string? errorMessageIfFailed, Exception? exceptionIfExists)
43+
public ValueTask OnEngineCompleteAsync(IServiceProvider serviceProvider, ILogger<ConsoleAppEngine> logger)
4144
{
42-
this.CompleteSuccessfully = (errorMessageIfFailed == null && exceptionIfExists == null);
43-
this.ErrorMessage = errorMessageIfFailed;
44-
this.Exception = exceptionIfExists;
45-
return innerInterceptor.OnEngineCompleteAsync(context, errorMessageIfFailed, exceptionIfExists);
45+
return innerInterceptor.OnEngineCompleteAsync(serviceProvider, logger);
4646
}
4747
}
4848

src/ConsoleAppFramework/CompositeConsoleAppInterceptor.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ public async ValueTask OnEngineBeginAsync(IServiceProvider serviceProvider, ILog
3333
exceptions.ThrowIfExists();
3434
}
3535

36-
public async ValueTask OnMethodEndAsync()
36+
public async ValueTask OnMethodEndAsync(ConsoleAppContext context, string? errorMessageIfFailed, Exception? exceptionIfExists)
3737
{
3838
var exceptions = new AggregateExceptionHolder();
3939
foreach (var item in interceptors)
4040
{
4141
try
4242
{
43-
await item.OnMethodEndAsync();
43+
await item.OnMethodEndAsync(context, errorMessageIfFailed, exceptionIfExists);
4444
}
4545
catch (Exception e)
4646
{
@@ -67,14 +67,14 @@ public async ValueTask OnMethodBeginAsync(ConsoleAppContext context)
6767
exceptions.ThrowIfExists();
6868
}
6969

70-
public async ValueTask OnEngineCompleteAsync(ConsoleAppContext context, string? errorMessageIfFailed, Exception? exceptionIfExists)
70+
public async ValueTask OnEngineCompleteAsync(IServiceProvider serviceProvider, ILogger<ConsoleAppEngine> logger)
7171
{
7272
var exceptions = new AggregateExceptionHolder();
7373
foreach (var item in interceptors)
7474
{
7575
try
7676
{
77-
await item.OnEngineCompleteAsync(context, errorMessageIfFailed, exceptionIfExists);
77+
await item.OnEngineCompleteAsync(serviceProvider, logger);
7878
}
7979
catch (Exception e)
8080
{

src/ConsoleAppFramework/ConsoleAppEngine.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public async Task RunAsync(Type type, MethodInfo method, string?[] args)
3030
{
3131
logger.LogTrace("ConsoleAppEngine.Run Start");
3232
var ctx = new ConsoleAppContext(args, DateTime.UtcNow, cancellationToken, logger);
33+
await interceptor.OnMethodBeginAsync(ctx);
3334
await RunCore(ctx, type, method, args, 1); // 0 is type selector
3435
}
3536

@@ -103,6 +104,7 @@ public async Task RunAsync(Type type, string[] args)
103104
else
104105
{
105106
Console.Write(new CommandHelpBuilder().BuildHelpMessage(methods, null));
107+
await interceptor.OnMethodEndAsync(ctx, null, null);
106108
return;
107109
}
108110
}
@@ -183,22 +185,22 @@ async Task RunCore(ConsoleAppContext ctx, Type type, MethodInfo methodInfo, stri
183185
}
184186
}
185187

186-
await interceptor.OnEngineCompleteAsync(ctx, null, null);
188+
await interceptor.OnMethodEndAsync(ctx, null, null);
187189
logger.LogTrace("ConsoleAppEngine.Run Complete Successfully");
188190
}
189191

190192
async ValueTask SetFailAsync(ConsoleAppContext context, string message)
191193
{
192194
Environment.ExitCode = 1;
193195
logger.LogError(message);
194-
await interceptor.OnEngineCompleteAsync(context, message, null);
196+
await interceptor.OnMethodEndAsync(context, message, null);
195197
}
196198

197199
async ValueTask SetFailAsync(ConsoleAppContext context, string message, Exception ex)
198200
{
199201
Environment.ExitCode = 1;
200202
logger.LogError(ex, message);
201-
await interceptor.OnEngineCompleteAsync(context, message, ex);
203+
await interceptor.OnMethodEndAsync(context, message, ex);
202204
}
203205

204206
bool TryGetInvokeArguments(ParameterInfo[] parameters, string?[] args, int argsOffset, out object[] invokeArgs, out string? errorMessage)

src/ConsoleAppFramework/ConsoleAppEngineService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public async Task StopAsync(CancellationToken cancellationToken)
8484
}
8585
finally
8686
{
87-
await interceptor.OnMethodEndAsync();
87+
await interceptor.OnEngineCompleteAsync(this.scope.ServiceProvider, logger);
8888
scope.Dispose();
8989
}
9090
}

src/ConsoleAppFramework/IConsoleAppInterceptor.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ public interface IConsoleAppInterceptor
1919
/// <summary>
2020
/// Called once when ConsoleAppMethod is finished.
2121
/// </summary>
22-
ValueTask OnMethodEndAsync();
22+
ValueTask OnMethodEndAsync(ConsoleAppContext context, string? errorMessageIfFailed, Exception? exceptionIfExists);
2323

2424
/// <summary>
2525
/// Called when ConsoleAppFramework is error or completed.
2626
/// </summary>
27-
ValueTask OnEngineCompleteAsync(ConsoleAppContext context, string? errorMessageIfFailed, Exception? exceptionIfExists);
27+
ValueTask OnEngineCompleteAsync(IServiceProvider serviceProvider, ILogger<ConsoleAppEngine> logger);
2828
}
2929

3030
public class NullConsoleAppInterceptor : IConsoleAppInterceptor
@@ -37,7 +37,7 @@ public ValueTask OnEngineBeginAsync(IServiceProvider serviceProvider, ILogger<Co
3737
return Empty;
3838
}
3939

40-
public ValueTask OnMethodEndAsync()
40+
public ValueTask OnMethodEndAsync(ConsoleAppContext context, string? errorMessageIfFailed, Exception? exceptionIfExists)
4141
{
4242
return Empty;
4343
}
@@ -47,7 +47,7 @@ public ValueTask OnMethodBeginAsync(ConsoleAppContext context)
4747
return Empty;
4848
}
4949

50-
public ValueTask OnEngineCompleteAsync(ConsoleAppContext context, string? errorMessageIfFailed, Exception? exceptionIfExists)
50+
public ValueTask OnEngineCompleteAsync(IServiceProvider serviceProvider, ILogger<ConsoleAppEngine> logger)
5151
{
5252
return Empty;
5353
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading.Tasks;
4+
using FluentAssertions;
5+
using Microsoft.Extensions.Hosting;
6+
using Microsoft.Extensions.Logging;
7+
using Xunit;
8+
9+
// ReSharper disable InconsistentNaming
10+
11+
namespace ConsoleAppFramework.Integration.Test
12+
{
13+
public partial class InterceptorTest
14+
{
15+
[Fact]
16+
public void Single()
17+
{
18+
using var console = new CaptureConsoleOutput();
19+
var args = new[] { "Cysharp" };
20+
var interceptor = new TestInterceptor();
21+
Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync<InterceptorTest_Single>(args, interceptor);
22+
23+
interceptor.Outputs.Should().Equal("OnEngineBeginAsync", "OnMethodBeginAsync", "OnMethodEndAsync", "OnEngineCompleteAsync");
24+
console.Output.Should().Contain("Hello Cysharp");
25+
}
26+
27+
//[Fact]
28+
//public void Single_Insufficient_Arguments()
29+
//{
30+
// using var console = new CaptureConsoleOutput();
31+
// var args = new string[] { };
32+
// var interceptor = new TestInterceptor();
33+
// Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync<InterceptorTest_Single>(args, interceptor);
34+
35+
// interceptor.Outputs.Should().Equal("OnEngineBeginAsync", "OnMethodBeginAsync", "OnMethodEndAsync", "OnEngineCompleteAsync");
36+
// console.Output.Should().Contain("Usage");
37+
//}
38+
39+
[Fact]
40+
public void Multi()
41+
{
42+
using var console = new CaptureConsoleOutput();
43+
var args = new[] { "hello", "Cysharp" };
44+
var interceptor = new TestInterceptor();
45+
Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync<InterceptorTest_Multi>(args, interceptor);
46+
47+
interceptor.Outputs.Should().Equal("OnEngineBeginAsync", "OnMethodBeginAsync", "OnMethodEndAsync", "OnEngineCompleteAsync");
48+
console.Output.Should().Contain("Hello Cysharp");
49+
}
50+
51+
[Fact]
52+
public void Multi_Insufficient_Arguments()
53+
{
54+
using var console = new CaptureConsoleOutput();
55+
var args = new[] { "Cysharp" };
56+
var interceptor = new TestInterceptor();
57+
Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync<InterceptorTest_Multi>(args, interceptor);
58+
59+
interceptor.Outputs.Should().Equal("OnEngineBeginAsync", "OnMethodBeginAsync", "OnMethodEndAsync", "OnEngineCompleteAsync");
60+
console.Output.Should().Contain("Usage");
61+
}
62+
63+
public class TestInterceptor : IConsoleAppInterceptor
64+
{
65+
public List<string> Outputs { get; } = new List<string>();
66+
67+
public ValueTask OnEngineBeginAsync(IServiceProvider serviceProvider, ILogger<ConsoleAppEngine> logger)
68+
{
69+
Outputs.Add("OnEngineBeginAsync");
70+
return default;
71+
}
72+
73+
public ValueTask OnMethodBeginAsync(ConsoleAppContext context)
74+
{
75+
Outputs.Add("OnMethodBeginAsync");
76+
return default;
77+
}
78+
79+
public ValueTask OnMethodEndAsync(ConsoleAppContext context, string? errorMessageIfFailed, Exception? exceptionIfExists)
80+
{
81+
Outputs.Add("OnMethodEndAsync");
82+
return default;
83+
}
84+
85+
public ValueTask OnEngineCompleteAsync(IServiceProvider serviceProvider, ILogger<ConsoleAppEngine> logger)
86+
{
87+
Outputs.Add("OnEngineCompleteAsync");
88+
return default;
89+
}
90+
}
91+
92+
public class InterceptorTest_Single : ConsoleAppBase
93+
{
94+
public void Hello([Option(0)]string name) => Console.WriteLine($"Hello {name}");
95+
}
96+
97+
public class InterceptorTest_Multi : ConsoleAppBase
98+
{
99+
[Command("hello")]
100+
public void Hello([Option(0)]string name) => Console.WriteLine($"Hello {name}");
101+
[Command("hello2")]
102+
public void Hello2([Option(0)]string name) => Console.WriteLine($"Hello {name}");
103+
}
104+
}
105+
}

0 commit comments

Comments
 (0)