docs: research AoT-ready DI container replacement for SimpleInjector#741
docs: research AoT-ready DI container replacement for SimpleInjector#741AndreaCuneo with Copilot wants to merge 4 commits into
Conversation
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
|
@copilot here the clarifications
Continue the work based on above |
…add ASP.NET Core cross-wiring PoC Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Clarifications recorded in §8 of the report and the recommendation finalized in §7 (commit 4d2ae67 — hash on branch): Pure.DI primary, MEDI-native fallback. Both PoCs re-verified under the actual target — Q3 explained (§8.3): today's composition roots are imperative runtime calls (
§7 assumes (a); please confirm or require (b). Also completed the pending ASP.NET Core cross-wiring PoC ( |
| public static bool LoggerWasInjected; | ||
|
|
||
| // ILogger<T> is a FRAMEWORK service: Pure.DI.MS resolves it from IServiceProvider (two-way cross-wiring) | ||
| public PingHandler(ILogger<PingHandler> logger) { LoggerWasInjected = logger is not null; } |
|
|
||
| public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) | ||
| { | ||
| Ran = true; |
|
@copilot regarding Q3 is important that OpenGeneric Decorator support is maintained. Is not acceptable that each Handler needs to be manually registered (use source generators) and that all matching are decorated. The goal is that during feature development, new Handlers are created and those must be guaranteed to be Decorated with all registered decorators. Add to Evaluation an example of Open Generic Decoration. |
…generator PoC Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Added Verified: CoreCLR, Important finding recorded in §6.8: Roslyn generators cannot see each other's output, so this scanner cannot feed Pure.DI's |
| foreach (var q in handlers.Select(h => h.Query).Distinct(SymbolEqualityComparer.Default).Cast<ITypeSymbol>()) | ||
| { | ||
| if (covered.Contains(q)) continue; | ||
| sb.AppendLine($" global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient<{validatorIface.Construct((INamedTypeSymbol)q).ToDisplayString(_fqn)}, {nullValidator.Construct((INamedTypeSymbol)q).ToDisplayString(_fqn)}>(services);"); | ||
| } |
SimpleInjector is not NativeAOT/trimming ready and blocks AoT adoption across Ark.Tools. This PR contains research only — no library code changed — into source-generation-based replacements, per the problem statement.
Report —
docs/aot-di-container-research.mdsrc/andsamples/rely on — open-generic decorators,RegisterConditionalfallback, runtime mediator dispatch,GetTypesToRegisterscanning,Verify()diagnostics, async scopes,Func<T>factories, ASP.NET Core cross-wiring.Expressionthroughout — a fork is effectively a rewrite).Ark.Tools.Solidfrom the container now; choose Pure.DI vs MEDI+Ark-owned-generator based on answers to §8.Feasibility PoCs —
evaluations/(isolated from slnx, CI, repo MSBuild)Two assert-based console projects replicating the Ark.Tools.Solid pipeline (open-generic decorator chain, validator fallback, mediator dispatch by runtime
Type, scopes), both passing on CoreCLR and on published NativeAOT binaries:PureDi.Evaluation— open-generic decorators via marker types work, but theTQuery : IQuery<TResult>constraint requires a custom marker:MediInjectio.Evaluation— Injectio's open-generic decoration crashes on NativeAOT out-of-the-box (runtime-closed decorator ctors trimmed). Proven fix an Ark generator would emit:[DynamicDependency(PublicConstructors, ...)]roots per closed pair, plus explicit instantiation for value-type generic args.dynamicdispatch inSimpleInjector*Processoris AoT-hostile regardless of container; both PoCs replace it with an AoT-safe default-interface-method bridge (IQueryHandlerBase<TResult>).Clarifications requested (report §8) — blocking final recommendation
ValidateOnBuildacceptable?Ark.Tools.SimpleInjector/Ex.csused downstream, or droppable?