Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/ConsoleAppFramework/Emitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,17 @@ public void EmitConfigure(SourceBuilder sb, DllReference dllReference)
}
sb.AppendLine("isRequireCallBuildAndSetServiceProvider = false;");

// keep an already set ServiceProvider(e.g. hosting integration's ToConsoleAppBuilder) when nothing was configured on the builder itself
var nothingConfigured = "configureServices == null && createServiceProvider == null && postConfigureServices == null";
if (dllReference.HasLogging)
{
nothingConfigured += " && configureLogging == null";
}
using (sb.BeginBlock($"if (ConsoleApp.ServiceProvider != null && {nothingConfigured})"))
{
sb.AppendLine("return;");
}

if (dllReference.HasConfiguration)
{
sb.AppendLine("var config = configuration;");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public CSharpGeneratorRunner()
baseCompilation = compilation;
}

public (Compilation, ImmutableArray<Diagnostic>) RunGenerator([StringSyntax("C#-test")] string source, string[]? preprocessorSymbols = null, AnalyzerConfigOptionsProvider? options = null)
public (Compilation, ImmutableArray<Diagnostic>) RunGenerator([StringSyntax("C#-test")] string source, string[]? preprocessorSymbols = null, AnalyzerConfigOptionsProvider? options = null, MetadataReference[]? additionalReferences = null)
{
if (preprocessorSymbols == null)
{
Expand Down Expand Up @@ -76,14 +76,18 @@ public static class Environment
}
""";
var compilation = baseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(source, parseOptions), CSharpSyntaxTree.ParseText(captureStaticCode, parseOptions));
if (additionalReferences != null)
{
compilation = compilation.AddReferences(additionalReferences);
}

driver.RunGeneratorsAndUpdateCompilation(compilation, out var newCompilation, out var diagnostics);
return (newCompilation, diagnostics);
}

public (Compilation Compilation, ImmutableArray<Diagnostic> Diagnostics, string Stdout, int ExitCode) CompileAndExecute(string source, string[] args, string[]? preprocessorSymbols = null, AnalyzerConfigOptionsProvider? options = null)
public (Compilation Compilation, ImmutableArray<Diagnostic> Diagnostics, string Stdout, int ExitCode) CompileAndExecute(string source, string[] args, string[]? preprocessorSymbols = null, AnalyzerConfigOptionsProvider? options = null, MetadataReference[]? additionalReferences = null)
{
var (compilation, diagnostics) = RunGenerator(source, preprocessorSymbols, options);
var (compilation, diagnostics) = RunGenerator(source, preprocessorSymbols, options, additionalReferences);

using var ms = new MemoryStream();
var emitResult = compilation.Emit(ms);
Expand Down Expand Up @@ -207,11 +211,11 @@ public async Task Verify(int id, [StringSyntax("C#-test")] string code, string d

// Execute and check stdout result

public async Task<int> Execute([StringSyntax("C#-test")] string code, string args, string expected, [CallerArgumentExpression("code")] string? codeExpr = null)
public async Task<int> Execute([StringSyntax("C#-test")] string code, string args, string expected, MetadataReference[]? additionalReferences = null, [CallerArgumentExpression("code")] string? codeExpr = null)
{
Console.WriteLine(codeExpr!);

var (compilation, diagnostics, stdout, exitCode) = CSharpGeneratorRunner.CompileAndExecute(code, args == "" ? [] : args.Split(' '));
var (compilation, diagnostics, stdout, exitCode) = CSharpGeneratorRunner.CompileAndExecute(code, args == "" ? [] : args.Split(' '), additionalReferences: additionalReferences);
foreach (var item in diagnostics)
{
Console.WriteLine(item.ToString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<ItemGroup>
<PackageReference Include="Basic.Reference.Assemblies" Version="1.8.4" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageReference Include="TUnit" Version="1.2.11" />
</ItemGroup>

Expand Down
34 changes: 33 additions & 1 deletion tests/ConsoleAppFramework.GeneratorTests/DITest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace ConsoleAppFramework.GeneratorTests;
using Microsoft.CodeAnalysis;

namespace ConsoleAppFramework.GeneratorTests;

[ClassDataSource<VerifyHelper>]
public class DITest(VerifyHelper verifier)
Expand Down Expand Up @@ -102,4 +104,34 @@ partial void BuildAndSetServiceProvider(ConsoleAppContext context)
}
""", "cmd test", "Test");
}

// https://github.com/Cysharp/ConsoleAppFramework/issues/251
[Test]
public async Task ConfigureGlobalOptionsKeepsExternallySetServiceProvider()
{
MetadataReference[] dependencyInjectionReferences =
[
MetadataReference.CreateFromFile(typeof(Microsoft.Extensions.DependencyInjection.IServiceCollection).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Microsoft.Extensions.DependencyInjection.ServiceProvider).Assembly.Location),
];

await verifier.Execute("""
#nullable enable
using Microsoft.Extensions.DependencyInjection;

var services = new ServiceCollection();
services.AddSingleton(new MyService("foo"));
ConsoleApp.ServiceProvider = services.BuildServiceProvider();

var app = ConsoleApp.Create();
app.ConfigureGlobalOptions((ref ConsoleApp.GlobalOptionsBuilder builder) => builder.AddGlobalOption<bool>("--verbose", ""));
app.Add("", ([FromServices] MyService service, int x) => Console.Write(service.Name + ":" + x));
app.Run(args);

public class MyService(string name)
{
public string Name => name;
}
""", args: "--x 10 --verbose", expected: "foo:10", additionalReferences: dependencyInjectionReferences);
}
}