Skip to content

Commit bb7fbe8

Browse files
committed
Add ConsoleAppBuilder.ConfigureContainer to setup other DI container library
1 parent e742271 commit bb7fbe8

File tree

4 files changed

+56
-7
lines changed

4 files changed

+56
-7
lines changed

ReadMe.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1223,7 +1223,7 @@ However, since the construction of the filters is performed before execution, au
12231223
If you have other applications such as ASP.NET in the entire project and want to use common DI and configuration set up using `Microsoft.Extensions.Hosting`, you can call `ToConsoleAppBuilder` from `IHostBuilder` or `HostApplicationBuilder`.
12241224

12251225
```csharp
1226-
// Package Import: Microsoft.Extensions.Hosting
1226+
// dotnet add package Microsoft.Extensions.Hosting
12271227
var app = Host.CreateApplicationBuilder()
12281228
.ToConsoleAppBuilder();
12291229
```
@@ -1232,6 +1232,21 @@ In this case, it builds the HostBuilder, creates a Scope for the ServiceProvider
12321232

12331233
ConsoleAppFramework has its own lifetime management (see the [CancellationToken(Gracefully Shutdown) and Timeout](#cancellationtokengracefully-shutdown-and-timeout) section), therefore it is handled correctly even without using `ConsoleLifetime`.
12341234

1235+
If you want to use other DI container(like [DryIoc](https://github.com/dadhi/DryIoc)) without Microsoft.Extensions.Hosting, you can use `ConfigureContainer` and setup `IServiceProviderFactory`.
1236+
1237+
```csharp
1238+
// dotnet add package Microsoft.Extensions.DependencyInjection
1239+
// dotnet add package DryIoc.Microsoft.DependencyInjection
1240+
var app = ConsoleApp.Create()
1241+
// setup DryIoc as the DI container
1242+
.ConfigureContainer(new DryIocServiceProviderFactory())
1243+
.ConfigureServices(services => services.AddSingleton<MyService>());
1244+
1245+
app.Add("", ([FromServices] MyService service) => { });
1246+
1247+
app.Run(args);
1248+
```
1249+
12351250
OpenTelemetry
12361251
---
12371252
It's important to be conscious of observability in console applications as well. Visualizing not just logging but also traces will be helpful for performance tuning and troubleshooting. In ConsoleAppFramework, you can use this smoothly by utilizing the OpenTelemetry support of HostApplicationBuilder.

sandbox/GeneratorSandbox/GeneratorSandbox.csproj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717

1818
<ItemGroup>
1919

20-
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.6" />
20+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.6" />
21+
<PackageReference Include="DryIoc.Microsoft.DependencyInjection" Version="6.2.0" />
22+
23+
<!--<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.6" />-->
2124
<!--
2225
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.6" />
2326
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.6" />

sandbox/GeneratorSandbox/Program.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11
using ConsoleAppFramework;
2+
using DryIoc.Microsoft.DependencyInjection;
23
using Microsoft.Extensions.DependencyInjection;
34
using System.Threading.Tasks.Dataflow;
45

56
// args = "some-command hello --global-flag flag-value -- more args here".Split(" ");
67

7-
var app = ConsoleApp.Create();
8-
app.ConfigureServices(services => services.AddSingleton<MyService>());
8+
var app = ConsoleApp.Create()
9+
// setup DryIoc as the DI container
10+
.ConfigureContainer(new DryIocServiceProviderFactory())
11+
.ConfigureServices(services => services.AddSingleton<MyService>());
912

10-
app.UseFilter<MyFilter>();
11-
app.Run(["cmd", "test"]);
13+
app.Add("", ([FromServices] MyService service) => { });
14+
15+
app.Run(args);
16+
17+
18+
19+
//app.UseFilter<MyFilter>();
20+
// app.Run(["cmd", "test"]);
1221

1322
public class MyService
1423
{

src/ConsoleAppFramework/Emitter.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,7 @@ public void EmitConfigure(SourceBuilder sb, DllReference dllReference)
801801
{
802802
sb.AppendLine("Action<ConsoleAppContext, IServiceCollection>? configureServices;");
803803
}
804+
sb.AppendLine("Func<IServiceCollection, IServiceProvider>? createServiceProvider;");
804805

805806
// methods
806807
if (dllReference.HasConfiguration)
@@ -851,6 +852,20 @@ public void EmitConfigure(SourceBuilder sb, DllReference dllReference)
851852
}
852853
}
853854

855+
sb.AppendLine();
856+
using (sb.BeginBlock("public ConsoleApp.ConsoleAppBuilder ConfigureContainer<TContainerBuilder>(IServiceProviderFactory<TContainerBuilder> factory, Action<TContainerBuilder>? configure = null) where TContainerBuilder : notnull"))
857+
{
858+
using (sb.BeginBlock("createServiceProvider = services =>"))
859+
{
860+
sb.AppendLine("var containerBuilder = factory.CreateBuilder(services);");
861+
sb.AppendLine("configure?.Invoke(containerBuilder);");
862+
sb.AppendLine("return factory.CreateServiceProvider(containerBuilder);");
863+
}
864+
sb.AppendLine(";");
865+
866+
sb.AppendLine("return this;");
867+
}
868+
854869
sb.AppendLine();
855870
}
856871

@@ -971,7 +986,14 @@ public void EmitConfigure(SourceBuilder sb, DllReference dllReference)
971986
}
972987
}
973988

974-
sb.AppendLine("ConsoleApp.ServiceProvider = services.BuildServiceProvider();");
989+
using (sb.BeginBlock("if (createServiceProvider != null)"))
990+
{
991+
sb.AppendLine("ConsoleApp.ServiceProvider = createServiceProvider.Invoke(services);");
992+
}
993+
using (sb.BeginBlock("else"))
994+
{
995+
sb.AppendLine("ConsoleApp.ServiceProvider = services.BuildServiceProvider();");
996+
}
975997
}
976998
}
977999

0 commit comments

Comments
 (0)