diff --git a/Directory.Packages.props b/Directory.Packages.props index ae946f6d17..237a523ec7 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -17,12 +17,13 @@ - + - - @@ -34,11 +35,17 @@ - + - + diff --git a/sources/SilkTouch/SilkTouch/Silk.NET.SilkTouch.csproj b/sources/SilkTouch/SilkTouch/Silk.NET.SilkTouch.csproj index afc4f29d09..c5cf2978db 100644 --- a/sources/SilkTouch/SilkTouch/Silk.NET.SilkTouch.csproj +++ b/sources/SilkTouch/SilkTouch/Silk.NET.SilkTouch.csproj @@ -6,8 +6,6 @@ - - diff --git a/sources/SilkTouch/SilkTouch/SilkTouchHost.cs b/sources/SilkTouch/SilkTouch/SilkTouchHost.cs index 144883a650..6deca44061 100644 --- a/sources/SilkTouch/SilkTouch/SilkTouchHost.cs +++ b/sources/SilkTouch/SilkTouch/SilkTouchHost.cs @@ -4,8 +4,6 @@ using System.CommandLine; using System.CommandLine.Invocation; using System.Diagnostics.CodeAnalysis; -using Autofac; -using Autofac.Extensions.DependencyInjection; using Microsoft.Build.Locator; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -13,7 +11,6 @@ using Silk.NET.SilkTouch.Caching; using Silk.NET.SilkTouch.Clang; using Silk.NET.SilkTouch.Mods; -using Silk.NET.SilkTouch.Mods.Bakery; using Silk.NET.SilkTouch.Sources; namespace Silk.NET.SilkTouch; @@ -102,10 +99,10 @@ public async Task RunAsync(string[] args) // Register MSBuild MSBuildLocator.RegisterDefaults(); - // Build container - var builder = new ContainerBuilder(); - Configure(builder, ctx); - await using ILifetimeScope container = builder.Build(); + // Build service provider + var services = new ServiceCollection(); + Configure(services, ctx); + await using var provider = services.BuildServiceProvider(); var jobKeysToRun = new HashSet( ctx.ParseResult.GetValueForOption(OnlyOption) ?? [], @@ -127,7 +124,7 @@ public async Task RunAsync(string[] args) return jobKeysToRun.Count == 0 || jobKeysToRun.Contains(job.Key); }); - var logger = container.Resolve>(); + var logger = provider.GetRequiredService>(); try { await Parallel.ForEachAsync( @@ -141,8 +138,11 @@ await Parallel.ForEachAsync( using var job = new SilkTouchJob( jobKvp.Key, jobKvp.Value.Config, - container, - builder => jobKvp.Value.Configure.Invoke(builder.SilkTouch()) + services => + { + ConfigureForward(provider, services); + jobKvp.Value.Configure.Invoke(services.SilkTouch()); + } ); await job.RunAsync(ct); @@ -173,11 +173,12 @@ private static void Exit(int exitCode) => Environment.Exit(exitCode); /// - /// Dependencies defined here will be shared by all jobs. + /// Dependencies defined here are only accessible to the host. + /// Make them available to the jobs by using . /// - private void Configure(ContainerBuilder builder, InvocationContext ctx) + private void Configure(IServiceCollection services, InvocationContext ctx) { - var services = new ServiceCollection() + services .AddLogging(builder => { builder.AddSimpleConsole(opts => @@ -193,8 +194,6 @@ private void Configure(ContainerBuilder builder, InvocationContext ctx) }) .AddOptions(); - builder.Populate(services); - { // Create config var config = new SilkTouchHostConfiguration() @@ -210,53 +209,45 @@ private void Configure(ContainerBuilder builder, InvocationContext ctx) ); } - builder.RegisterInstance(config).SingleInstance(); - - builder - .RegisterType() - .As() - .SingleInstance(); - - builder.RegisterType().SingleInstance(); - - builder - .RegisterType() - .AsSelf() - .AsImplementedInterfaces() - .SingleInstance(); - - builder.RegisterType().As().SingleInstance(); - - builder.RegisterType().As().SingleInstance(); + services.AddSingleton(config); - builder.RegisterType().As().SingleInstance(); - - builder.RegisterType().As().SingleInstance(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); if (OperatingSystem.IsWindows()) { - builder - .RegisterType() - .As() - .SingleInstance(); + services.AddSingleton(); } else if (OperatingSystem.IsMacOS()) { - builder - .RegisterType() - .As() - .SingleInstance(); + services.AddSingleton(); } else { - builder - .RegisterType() - .As() - .SingleInstance(); + services.AddSingleton(); } } } + /// + /// Dependencies defined here will be available to jobs. + /// + private void ConfigureForward(IServiceProvider host, IServiceCollection services) + { + // Prefer to match the registration order above + services.AddSingleton(host.GetRequiredService()); + services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); + + services.AddSingleton(host.GetRequiredService()); + services.AddSingleton(host.GetRequiredService()); + services.AddSingleton(host.GetRequiredService()); + services.AddSingleton(host.GetRequiredService()); + services.AddSingleton(host.GetRequiredService()); + } + private record JobDefinition( SilkTouchConfiguration Config, Action Configure diff --git a/sources/SilkTouch/SilkTouch/SilkTouchJob.cs b/sources/SilkTouch/SilkTouch/SilkTouchJob.cs index d98398146f..5e66213f28 100644 --- a/sources/SilkTouch/SilkTouch/SilkTouchJob.cs +++ b/sources/SilkTouch/SilkTouch/SilkTouchJob.cs @@ -2,9 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; -using Autofac; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Silk.NET.SilkTouch.Clang; using Silk.NET.SilkTouch.Mods; +using Silk.NET.SilkTouch.Mods.Bakery; using Silk.NET.SilkTouch.Mods.Transformation; using Silk.NET.SilkTouch.Sources; using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; @@ -16,7 +18,7 @@ namespace Silk.NET.SilkTouch; /// internal class SilkTouchJob : IDisposable { - private readonly ILifetimeScope _container; + private readonly ServiceProvider _provider; private readonly ILogger _logger; private readonly IInputResolver _inputResolver; @@ -43,36 +45,37 @@ internal class SilkTouchJob : IDisposable /// /// The job key. /// The job config. - /// The parent container. Should be the one from the . /// - /// The action that configures the dependency container used by this job. + /// The action that configures the services used by this job. /// You'll want to register SilkTouch mods during this action. See . /// public SilkTouchJob( string key, SilkTouchConfiguration config, - ILifetimeScope parentContainer, - Action configure + Action configure ) { Key = key; Config = config; - _logger = parentContainer.Resolve>(); - _inputResolver = parentContainer.Resolve(); - _container = parentContainer.BeginLifetimeScope(builder => + var services = new ServiceCollection(); { // Register default dependencies - builder.RegisterType().SingleInstance(); - builder.RegisterType().SingleInstance(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); // Register user defined dependencies - configure.Invoke(builder); - }); + configure.Invoke(services); + } - _modContextFactory = _container.Resolve(); - _documentFactory = _container.Resolve(); - Mods = _container.Resolve(); + _provider = services.BuildServiceProvider(); + _logger = _provider.GetRequiredService>(); + _inputResolver = _provider.GetRequiredService(); + _modContextFactory = _provider.GetRequiredService(); + _documentFactory = _provider.GetRequiredService(); + Mods = _provider.GetRequiredService>().ToArray(); } /// @@ -175,5 +178,5 @@ await File.ReadAllTextAsync(Config.DefaultLicenseHeader, ct) } /// - public void Dispose() => _container.Dispose(); + public void Dispose() => _provider.Dispose(); } diff --git a/sources/SilkTouch/SilkTouch/SilkTouchRegistrationExtensions.cs b/sources/SilkTouch/SilkTouch/SilkTouchRegistrationExtensions.cs index c6dc9061ba..7b397ccac5 100644 --- a/sources/SilkTouch/SilkTouch/SilkTouchRegistrationExtensions.cs +++ b/sources/SilkTouch/SilkTouch/SilkTouchRegistrationExtensions.cs @@ -1,8 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Autofac; -using Autofac.Builder; +using Microsoft.Extensions.DependencyInjection; using Silk.NET.SilkTouch.Clang; using Silk.NET.SilkTouch.Mods; using Silk.NET.SilkTouch.Mods.Transformation; @@ -18,8 +17,8 @@ public static class SilkTouchRegistrationExtensions /// Entrypoint to the rest of the SilkTouch registration methods. /// Begins a . /// - public static SilkTouchRegistrationContext SilkTouch(this ContainerBuilder builder) => - new(builder); + public static SilkTouchRegistrationContext SilkTouch(this IServiceCollection services) => + new(services); // Non-mods extension(SilkTouchRegistrationContext context) @@ -42,11 +41,7 @@ public SilkTouchRegistrationContext WithDefaultFunctionTransformers( /// public SilkTouchRegistrationContext WithPtrRefTransformer() { - context - .Builder.RegisterType() - .AsImplementedInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsInterfaces(); return context; } @@ -58,17 +53,9 @@ public SilkTouchRegistrationContext WithBoolTransformer( BoolTransformer.Configuration? boolTransformerConfig = null ) { - context - .Builder.RegisterType() - .WithParameter( - new TypedParameter( - typeof(BoolTransformer.Configuration), - boolTransformerConfig ?? new() - ) - ) - .AsImplementedInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsInterfaces( + boolTransformerConfig ?? new() + ); return context; } @@ -78,11 +65,7 @@ public SilkTouchRegistrationContext WithBoolTransformer( /// public SilkTouchRegistrationContext WithArrayParameterTransformer() { - context - .Builder.RegisterType() - .AsImplementedInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsInterfaces(); return context; } } @@ -97,14 +80,7 @@ public SilkTouchRegistrationContext AddApiProfiles( AddApiProfiles.Configuration? config = null ) { - context - .Builder.RegisterType() - .WithParameter( - new TypedParameter(typeof(AddApiProfiles.Configuration), config ?? new()) - ) - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(config ?? new()); return context; } @@ -113,12 +89,7 @@ public SilkTouchRegistrationContext AddApiProfiles( /// public SilkTouchRegistrationContext ClangScraper(ClangScraper.Configuration config) { - context - .Builder.RegisterType() - .WithParameter(new TypedParameter(typeof(ClangScraper.Configuration), config)) - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(config); return context; } @@ -127,14 +98,7 @@ public SilkTouchRegistrationContext ClangScraper(ClangScraper.Configuration conf /// public SilkTouchRegistrationContext AddIncludes(AddIncludes.Configuration? config = null) { - context - .Builder.RegisterType() - .WithParameter( - new TypedParameter(typeof(AddIncludes.Configuration), config ?? new()) - ) - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(config ?? new()); return context; } @@ -143,12 +107,7 @@ public SilkTouchRegistrationContext AddIncludes(AddIncludes.Configuration? confi /// public SilkTouchRegistrationContext AddOpaqueStructs(AddOpaqueStructs.Configuration config) { - context - .Builder.RegisterType() - .WithParameter(new TypedParameter(typeof(AddOpaqueStructs.Configuration), config)) - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(config); return context; } @@ -157,14 +116,7 @@ public SilkTouchRegistrationContext AddOpaqueStructs(AddOpaqueStructs.Configurat /// public SilkTouchRegistrationContext AddVTables(AddVTables.Configuration? config = null) { - context - .Builder.RegisterType() - .WithParameter( - new TypedParameter(typeof(AddVTables.Configuration), config ?? new()) - ) - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(config ?? new()); return context; } @@ -173,12 +125,7 @@ public SilkTouchRegistrationContext AddVTables(AddVTables.Configuration? config /// public SilkTouchRegistrationContext BakeSourceSets(BakeSourceSets.Configuration config) { - context - .Builder.RegisterType() - .WithParameter(new TypedParameter(typeof(BakeSourceSets.Configuration), config)) - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(config); return context; } @@ -187,12 +134,7 @@ public SilkTouchRegistrationContext BakeSourceSets(BakeSourceSets.Configuration /// public SilkTouchRegistrationContext ChangeNamespace(ChangeNamespace.Configuration config) { - context - .Builder.RegisterType() - .WithParameter(new TypedParameter(typeof(ChangeNamespace.Configuration), config)) - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(config); return context; } @@ -203,12 +145,7 @@ public SilkTouchRegistrationContext ChangeNativeClass( ChangeNativeClass.Configuration config ) { - context - .Builder.RegisterType() - .WithParameter(new TypedParameter(typeof(ChangeNativeClass.Configuration), config)) - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(config); return context; } @@ -217,11 +154,7 @@ ChangeNativeClass.Configuration config /// public SilkTouchRegistrationContext ExtractEnumConstants() { - context - .Builder.RegisterType() - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(); return context; } @@ -230,11 +163,7 @@ public SilkTouchRegistrationContext ExtractEnumConstants() /// public SilkTouchRegistrationContext ExtractFunctionPointers() { - context - .Builder.RegisterType() - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(); return context; } @@ -243,11 +172,7 @@ public SilkTouchRegistrationContext ExtractFunctionPointers() /// public SilkTouchRegistrationContext ExtractHandles() { - context - .Builder.RegisterType() - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(); return context; } @@ -256,11 +181,7 @@ public SilkTouchRegistrationContext ExtractHandles() /// public SilkTouchRegistrationContext ExtractNestedTypes() { - context - .Builder.RegisterType() - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(); return context; } @@ -271,14 +192,7 @@ public SilkTouchRegistrationContext IdentifySharedPrefixes( IdentifySharedPrefixes.Configuration? config = null ) { - context - .Builder.RegisterType() - .WithParameter( - new TypedParameter(typeof(IdentifySharedPrefixes.Configuration), config) - ) - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(config); return context; } @@ -289,14 +203,7 @@ public SilkTouchRegistrationContext InterceptNativeFunctions( InterceptNativeFunctions.Configuration? config = null ) { - context - .Builder.RegisterType() - .WithParameter( - new TypedParameter(typeof(InterceptNativeFunctions.Configuration), config) - ) - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(config); return context; } @@ -305,11 +212,7 @@ public SilkTouchRegistrationContext InterceptNativeFunctions( /// public SilkTouchRegistrationContext MarkNativeNames() { - context - .Builder.RegisterType() - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(); return context; } @@ -320,14 +223,7 @@ public SilkTouchRegistrationContext MixKhronosData( MixKhronosData.Configuration? config = null ) { - context - .Builder.RegisterType() - .WithParameter( - new TypedParameter(typeof(MixKhronosData.Configuration), config ?? new()) - ) - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(config ?? new()); return context; } @@ -338,14 +234,7 @@ public SilkTouchRegistrationContext PrettifyNames( PrettifyNames.Configuration? config = null ) { - context - .Builder.RegisterType() - .WithParameter( - new TypedParameter(typeof(PrettifyNames.Configuration), config ?? new()) - ) - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(config ?? new()); return context; } @@ -356,14 +245,7 @@ public SilkTouchRegistrationContext StripAttributes( StripAttributes.Configuration? config = null ) { - context - .Builder.RegisterType() - .WithParameter( - new TypedParameter(typeof(StripAttributes.Configuration), config ?? new()) - ) - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(config ?? new()); return context; } @@ -374,14 +256,7 @@ public SilkTouchRegistrationContext TransformEnums( TransformEnums.Configuration? config = null ) { - context - .Builder.RegisterType() - .WithParameter( - new TypedParameter(typeof(TransformEnums.Configuration), config ?? new()) - ) - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(config ?? new()); return context; } @@ -390,11 +265,7 @@ public SilkTouchRegistrationContext TransformEnums( /// public SilkTouchRegistrationContext TransformFunctions() { - context - .Builder.RegisterType() - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(); return context; } @@ -405,14 +276,9 @@ public SilkTouchRegistrationContext TransformHandles( TransformHandles.Configuration? config = null ) { - context - .Builder.RegisterType() - .WithParameter( - new TypedParameter(typeof(TransformHandles.Configuration), config ?? new()) - ) - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces( + config ?? new() + ); return context; } @@ -423,46 +289,58 @@ public SilkTouchRegistrationContext TransformProperties( TransformProperties.Configuration? config = null ) { - context - .Builder.RegisterType() - .WithParameter( - new TypedParameter(typeof(TransformProperties.Configuration), config) - ) - .AsHierarchyAndInterfaces() - .SingleInstance(); - + context.Services.AddSingletonAsHierarchyAndInterfaces(config); return context; } } - extension( - IRegistrationBuilder registration - ) - where TConcreteActivatorData : IConcreteActivatorData + extension(IServiceCollection services) { - private IRegistrationBuilder< - TLimit, - TConcreteActivatorData, - SingleRegistrationStyle - > AsHierarchyAndInterfaces() - { - var type = registration.ActivatorData.Activator.LimitType; - var typesToRegister = new HashSet(); - typesToRegister.UnionWith(type.GetInterfaces()); + private IServiceCollection AddSingletonAsInterfaces(object? parameter = null) + where T : class => services.AddSingletonAs(typeof(T).GetInterfaces(), parameter); - var current = type; + private IServiceCollection AddSingletonAsHierarchyAndInterfaces(object? parameter = null) + where T : class + { + var types = new HashSet(typeof(T).GetInterfaces()); + var current = typeof(T); while (current != null) { - typesToRegister.Add(current); + types.Add(current); current = current.BaseType; } - return registration.As(typesToRegister.ToArray()); + return services.AddSingletonAs(types, parameter); + } + + private IServiceCollection AddSingletonAs(IEnumerable types, object? parameter) + where T : class + { + var key = new object(); + object[] parameters = parameter is null ? [] : [parameter]; + + services.AddKeyedSingleton( + typeof(T), + key, + (sp, _) => ActivatorUtilities.CreateInstance(sp, parameters) + ); + + services.AddSingleton(typeof(T), sp => sp.GetRequiredKeyedService(key)); + + foreach (var type in types) + { + if (type != typeof(T)) + { + services.AddSingleton(type, sp => sp.GetRequiredKeyedService(key)); + } + } + + return services; } } /// - /// Helper for registering SilkTouch to a + /// Helper for registering SilkTouch to a /// - public record struct SilkTouchRegistrationContext(ContainerBuilder Builder); + public record struct SilkTouchRegistrationContext(IServiceCollection Services); }