Skip to content

Commit 3082cfc

Browse files
authored
Merge pull request #191 from Cysharp/host_start
HostApplicationBuilder.ToConsoleApp host calls StartAsync and StopAsy…
2 parents b853697 + 27c083c commit 3082cfc

File tree

4 files changed

+196
-55
lines changed

4 files changed

+196
-55
lines changed

sandbox/GeneratorSandbox/GeneratorSandbox.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<ItemGroup>
2020
<!--<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.0" />
2121
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="9.0.0" />-->
22-
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.6" />
22+
<!--<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.6" />-->
2323
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
2424
<!--<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" />-->
2525
<!--<PackageReference Include="ZLogger" Version="2.5.9" />-->

sandbox/GeneratorSandbox/Program.cs

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,64 @@
22

33
using CommunityToolkit.Mvvm.ComponentModel;
44
using ConsoleAppFramework;
5-
using Microsoft.Extensions.DependencyInjection;
6-
using Microsoft.Extensions.Hosting;
5+
//using Microsoft.Extensions.DependencyInjection;
6+
//using Microsoft.Extensions.Hosting;
7+
using System.Transactions;
78

89
[assembly: ConsoleAppFrameworkGeneratorOptions(DisableNamingConversion = true)]
910

1011
args = ["TestCommand", "Run"];
1112

12-
var builder = Host.CreateApplicationBuilder(args);
13-
var services = builder.Services;
13+
//var builder = Host.CreateApplicationBuilder(args);
14+
//var services = builder.Services;
1415

15-
services.AddSingleton<ITest, Test>();
16-
services.AddKeyedSingleton<ITest, KeyedTest>("Key");
16+
//services.AddSingleton<ITest, Test>();
17+
//services.AddKeyedSingleton<ITest, KeyedTest>("Key");
1718

1819

19-
MyObj obj = new();
20-
while (obj.Data.Count < 1)
21-
{
22-
obj.Data.Add(0); // <-- CAF008 error here
23-
}
20+
//MyObj obj = new();
21+
//while (obj.Data.Count < 1)
22+
//{
23+
// obj.Data.Add(0); // <-- CAF008 error here
24+
//}
25+
26+
27+
////builder.Build();
28+
////IHost host;
29+
////host.Run();
30+
2431

25-
var app = builder.ToConsoleAppBuilder();
32+
33+
//var app = builder.ToConsoleAppBuilder();
2634
// var app = ConsoleApp.Create();
2735
//for (int i = 0; i < 10; i++)
2836
//{
2937
// app.Add("foo", (int x) => { });
3038
//}
3139

32-
app.Run(args);
40+
41+
// var hsot = ConsoleApp.ServiceProvider.GetService(typeof(IHost));
42+
//public void Run(string[] args)
43+
//{
44+
// BuildAndSetServiceProvider();
45+
// try
46+
// {
47+
// RunCore(args);
48+
// }
49+
// finally
50+
// {
51+
// if (ServiceProvider is IDisposable d)
52+
// {
53+
// d.Dispose();
54+
// }
55+
// }
56+
//}
57+
58+
var app = ConsoleApp.Create();
59+
60+
await app.RunAsync(args);
61+
62+
//await app.RunAsync(args);
3363

3464
interface ITest
3565
{
@@ -46,15 +76,15 @@ class KeyedTest : ITest
4676
public int Value { get; set; } = 2;
4777
}
4878

49-
[RegisterCommands(nameof(TestCommand))]
50-
class TestCommand([FromKeyedServices("Key")] ITest test)
51-
{
52-
public void Run()
53-
{
54-
// This value should be 2 but 1 displayed
55-
Console.WriteLine(test.Value);
56-
}
57-
}
79+
//[RegisterCommands(nameof(TestCommand))]
80+
//class TestCommand([FromKeyedServices("Key")] ITest test)
81+
//{
82+
// public void Run()
83+
// {
84+
// // This value should be 2 but 1 displayed
85+
// Console.WriteLine(test.Value);
86+
// }
87+
//}
5888

5989
public partial class MyObj : ObservableObject
6090
{
@@ -359,3 +389,4 @@ public partial class MyObj : ObservableObject
359389

360390

361391
//}
392+

src/ConsoleAppFramework/ConsoleAppBaseCode.cs

Lines changed: 125 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,73 @@ public void Add<T>(string commandPath) { }
478478
[System.Diagnostics.Conditional("DEBUG")]
479479
public void UseFilter<T>() where T : ConsoleAppFilter { }
480480
481+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
482+
partial void AddCore(string commandName, Delegate command);
483+
484+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
485+
partial void RunCore(string[] args);
486+
487+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
488+
partial void RunAsyncCore(string[] args, ref Task result);
489+
490+
partial void BuildAndSetServiceProvider();
491+
492+
static partial void ShowHelp(int helpId);
493+
494+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
495+
static bool TryShowHelpOrVersion(ReadOnlySpan<string> args, int requiredParameterCount, int helpId)
496+
{
497+
if (args.Length == 0)
498+
{
499+
if (requiredParameterCount == 0) return false;
500+
501+
ShowHelp(helpId);
502+
return true;
503+
}
504+
505+
if (args.Length == 1)
506+
{
507+
switch (args[0])
508+
{
509+
case "--version":
510+
ShowVersion();
511+
return true;
512+
case "-h":
513+
case "--help":
514+
ShowHelp(helpId);
515+
return true;
516+
default:
517+
break;
518+
}
519+
}
520+
521+
return false;
522+
}
523+
}
524+
}
525+
""";
526+
527+
public const string ConsoleAppBuilderRunStandard = """
528+
// <auto-generated/>
529+
#nullable enable
530+
#pragma warning disable
531+
532+
namespace ConsoleAppFramework;
533+
534+
using System;
535+
using System.Text;
536+
using System.Reflection;
537+
using System.Threading;
538+
using System.Threading.Tasks;
539+
using System.Runtime.InteropServices;
540+
using System.Runtime.CompilerServices;
541+
using System.Diagnostics.CodeAnalysis;
542+
using System.ComponentModel.DataAnnotations;
543+
544+
internal static partial class ConsoleApp
545+
{
546+
internal partial class ConsoleAppBuilder
547+
{
481548
public void Run(string[] args)
482549
{
483550
BuildAndSetServiceProvider();
@@ -518,48 +585,76 @@ public async Task RunAsync(string[] args)
518585
}
519586
}
520587
}
588+
}
589+
}
590+
""";
521591

522-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
523-
partial void AddCore(string commandName, Delegate command);
524-
525-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
526-
partial void RunCore(string[] args);
527-
528-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
529-
partial void RunAsyncCore(string[] args, ref Task result);
592+
public const string ConsoleAppBuilderRunWithHost = """
593+
// <auto-generated/>
594+
#nullable enable
595+
#pragma warning disable
530596
531-
partial void BuildAndSetServiceProvider();
597+
namespace ConsoleAppFramework;
532598
533-
static partial void ShowHelp(int helpId);
599+
using System;
600+
using System.Text;
601+
using System.Reflection;
602+
using System.Threading;
603+
using System.Threading.Tasks;
604+
using System.Runtime.InteropServices;
605+
using System.Runtime.CompilerServices;
606+
using System.Diagnostics.CodeAnalysis;
607+
using System.ComponentModel.DataAnnotations;
534608
535-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
536-
static bool TryShowHelpOrVersion(ReadOnlySpan<string> args, int requiredParameterCount, int helpId)
609+
internal static partial class ConsoleApp
610+
{
611+
internal partial class ConsoleAppBuilder
612+
{
613+
public void Run(string[] args)
537614
{
538-
if (args.Length == 0)
615+
BuildAndSetServiceProvider();
616+
Microsoft.Extensions.Hosting.IHost? host = ConsoleApp.ServiceProvider?.GetService(typeof(Microsoft.Extensions.Hosting.IHost)) as Microsoft.Extensions.Hosting.IHost;
617+
try
539618
{
540-
if (requiredParameterCount == 0) return false;
541-
542-
ShowHelp(helpId);
543-
return true;
619+
host?.StartAsync().GetAwaiter().GetResult();
620+
RunCore(args);
544621
}
545-
546-
if (args.Length == 1)
622+
finally
547623
{
548-
switch (args[0])
624+
host?.StopAsync().GetAwaiter().GetResult();
625+
if (ServiceProvider is IDisposable d)
549626
{
550-
case "--version":
551-
ShowVersion();
552-
return true;
553-
case "-h":
554-
case "--help":
555-
ShowHelp(helpId);
556-
return true;
557-
default:
558-
break;
627+
d.Dispose();
559628
}
560629
}
630+
}
561631
562-
return false;
632+
public async Task RunAsync(string[] args)
633+
{
634+
BuildAndSetServiceProvider();
635+
Microsoft.Extensions.Hosting.IHost? host = ConsoleApp.ServiceProvider?.GetService(typeof(Microsoft.Extensions.Hosting.IHost)) as Microsoft.Extensions.Hosting.IHost;
636+
try
637+
{
638+
await host?.StartAsync();
639+
Task? task = null;
640+
RunAsyncCore(args, ref task!);
641+
if (task != null)
642+
{
643+
await task;
644+
}
645+
}
646+
finally
647+
{
648+
await host?.StopAsync();
649+
if (ServiceProvider is IAsyncDisposable ad)
650+
{
651+
await ad.DisposeAsync();
652+
}
653+
else if (ServiceProvider is IDisposable d)
654+
{
655+
d.Dispose();
656+
}
657+
}
563658
}
564659
}
565660
}

src/ConsoleAppFramework/ConsoleAppGenerator.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,10 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
178178
})
179179
.WithTrackingName("ConsoleApp.Builder.4_CombineSelected");
180180

181-
context.RegisterSourceOutput(combined, EmitConsoleAppBuilder);
181+
var finalCombined = combined.Combine(hasReferences)
182+
.WithTrackingName("ConsoleApp.Builder.5_WithReferences");
183+
184+
context.RegisterSourceOutput(finalCombined, EmitConsoleAppBuilder);
182185
}
183186

184187
static void EmitConsoleAppTemplateSource(IncrementalGeneratorPostInitializationContext context)
@@ -222,8 +225,20 @@ static void EmitConsoleAppRun(SourceProductionContext sourceProductionContext, C
222225
sourceProductionContext.AddSource("ConsoleApp.Run.Help.g.cs", help.ToString().ReplaceLineEndings());
223226
}
224227

225-
static void EmitConsoleAppBuilder(SourceProductionContext sourceProductionContext, CollectBuilderContext collectBuilderContext)
228+
static void EmitConsoleAppBuilder(SourceProductionContext sourceProductionContext, (CollectBuilderContext, DllReference) builderContext)
226229
{
230+
(CollectBuilderContext collectBuilderContext, DllReference dllReference) = builderContext;
231+
232+
// build static Run
233+
if (dllReference.HasHost)
234+
{
235+
sourceProductionContext.AddSource("ConsoleApp.Builder.Run.g.cs", ConsoleAppBaseCode.ConsoleAppBuilderRunWithHost.ReplaceLineEndings());
236+
}
237+
else
238+
{
239+
sourceProductionContext.AddSource("ConsoleApp.Builder.Run.g.cs", ConsoleAppBaseCode.ConsoleAppBuilderRunStandard.ReplaceLineEndings());
240+
}
241+
227242
var reporter = collectBuilderContext.DiagnosticReporter;
228243
var hasRun = collectBuilderContext.HasRun;
229244
var hasRunAsync = collectBuilderContext.HasRunAsync;

0 commit comments

Comments
 (0)