diff --git a/Directory.Build.props b/Directory.Build.props index aadab28..1bf3aa7 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -3,7 +3,7 @@ - 1.0.4-beta + 1.0.5-beta MIT diff --git a/docs/changelog.md b/docs/changelog.md index 7a55425..f97e424 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -10,6 +10,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - No changes yet +## [1.0.5-beta] - 2025-11-14 + +### Changed +- **Migrated code generation from StringBuilder to Scriban templates** for improved maintainability and readability + - Unified template generates all interceptor code for 8 registration kinds + - Conditional logic handles variations (keyed, factory, instance, two-type-params) + - Template caching with `ConcurrentDictionary` for performance + - Strongly-typed `RegistrationModel` (readonly record struct) for zero-boxing overhead +- **Code cleanup** - Removed 570+ lines of StringBuilder emission code + - Simplified `InterceptorEmitter.cs` from 440+ lines to ~70 lines + - Removed individual template files (Common/InterceptsLocationAttribute, DecoratorKeys, DecoratorFactory) + - Single unified template: `DecoWeaverInterceptors.scriban` +- **Comment reduction** - Removed generic "Register X" comments, kept only valuable WHY comments + - "Create nested key to avoid circular resolution" - explains nested key purpose + - "Compose decorators (innermost to outermost)" - explains decorator ordering + +### Added +- Added dependency: `Scriban 6.5.0` and `Microsoft.CSharp 4.7.0` (for Scriban's dynamic features) +- Template resource format: `Templates.{FileName}.scriban` embedded in assembly +- `TemplateHelper.cs` with template loading and caching infrastructure +- `DecoWeaverInterceptorsSources.cs` with strongly-typed model generation + +### Technical Details +- Template compilation is one-time cost with caching - no performance impact +- No functional changes - generated code is equivalent (except comment reduction) +- All 49 tests passing with updated snapshots +- Template uses Scriban's `{{-` syntax for whitespace control + ## [1.0.4-beta] - 2025-11-13 ### Added diff --git a/releasenotes.props b/releasenotes.props index 0ff388a..65fe0d0 100644 --- a/releasenotes.props +++ b/releasenotes.props @@ -188,6 +188,44 @@ This release adds support for singleton instance registrations, completing issue * Changelog: https://layeredcraft.github.io/decoweaver/changelog/ * GitHub: https://github.com/layeredcraft/decoweaver +]]> + + + + ` for performance + - Strongly-typed `RegistrationModel` (readonly record struct) for zero-boxing overhead +* **Code cleanup** - Removed 570+ lines of StringBuilder emission code + - Simplified `InterceptorEmitter.cs` from 440+ lines to ~70 lines + - Removed individual template files (Common/InterceptsLocationAttribute, DecoratorKeys, DecoratorFactory) + - Single unified template: `DecoWeaverInterceptors.scriban` +* **Comment reduction** - Removed generic "Register X" comments, kept only valuable WHY comments: + - "Create nested key to avoid circular resolution" - explains nested key purpose + - "Compose decorators (innermost to outermost)" - explains decorator ordering + +### Technical Details + +* Added dependency: `Scriban 6.5.0` and `Microsoft.CSharp 4.7.0` (for Scriban's dynamic features) +* Template resource format: `Templates.{FileName}.scriban` embedded in assembly +* No functional changes - generated code is equivalent (except comment reduction) +* All 49 tests passing with updated snapshots +* Build performance unchanged - template compilation is one-time cost with caching + +### Documentation + +* Full documentation: https://layeredcraft.github.io/decoweaver/ +* Changelog: https://layeredcraft.github.io/decoweaver/changelog/ +* GitHub: https://github.com/layeredcraft/decoweaver + ]]> diff --git a/src/LayeredCraft.DecoWeaver.Attributes/LayeredCraft.DecoWeaver.Attributes.csproj b/src/LayeredCraft.DecoWeaver.Attributes/LayeredCraft.DecoWeaver.Attributes.csproj index becc141..a9f7ffc 100644 --- a/src/LayeredCraft.DecoWeaver.Attributes/LayeredCraft.DecoWeaver.Attributes.csproj +++ b/src/LayeredCraft.DecoWeaver.Attributes/LayeredCraft.DecoWeaver.Attributes.csproj @@ -11,7 +11,7 @@ true - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/LayeredCraft.DecoWeaver.Generators/Emit/InterceptorEmitter.cs b/src/LayeredCraft.DecoWeaver.Generators/Emit/InterceptorEmitter.cs index 882bdd5..59cd149 100644 --- a/src/LayeredCraft.DecoWeaver.Generators/Emit/InterceptorEmitter.cs +++ b/src/LayeredCraft.DecoWeaver.Generators/Emit/InterceptorEmitter.cs @@ -1,7 +1,7 @@ // DecoWeaver/Emit/InterceptorEmitter.cs -using System.Text; using DecoWeaver.Model; +using DecoWeaver.OutputGenerators; using DecoWeaver.Providers; using DecoWeaver.Util; using Microsoft.CodeAnalysis.CSharp; @@ -15,528 +15,30 @@ public static string EmitClosedGenericInterceptors( EquatableArray registrations, Dictionary> decoratorsByImplementation) { - var sb = new StringBuilder(16_384); - - sb.AppendLine("// "); - sb.AppendLine("#nullable enable"); - sb.AppendLine(); - - EmitInterceptsLocationAttribute(sb); - - sb.AppendLine("namespace DecoWeaver.Generated"); - sb.AppendLine("{"); - sb.AppendLine(" using System;"); - sb.AppendLine(" using System.Collections.Generic;"); - sb.AppendLine(" using System.Diagnostics;"); - sb.AppendLine(" using System.Runtime.CompilerServices;"); - sb.AppendLine(" using Microsoft.Extensions.DependencyInjection;"); - sb.AppendLine(); - - sb.AppendLine(" file static class DecoWeaverInterceptors"); - sb.AppendLine(" {"); - - // Group registrations by lifetime + // Group registrations by lifetime to preserve ordering var byLifetime = registrations .GroupBy(r => r.Lifetime) .ToDictionary(g => g.Key, g => g.ToList()); - // Emit one interceptor method per registration + // Convert all registrations to template models + var models = new List(); var methodIndex = 0; + foreach (var (lifetime, regs) in byLifetime) { foreach (var reg in regs) { - EmitSingleInterceptor(sb, lifetime, reg, methodIndex++, decoratorsByImplementation); - } - } - - EmitHelpers(sb); - - sb.AppendLine(" }"); // class - sb.AppendLine("}"); // namespace - return sb.ToString(); - } - - private static void EmitInterceptsLocationAttribute(StringBuilder sb) - { - sb.AppendLine("namespace System.Runtime.CompilerServices"); - sb.AppendLine("{"); - sb.AppendLine(" file sealed class InterceptsLocationAttribute : Attribute"); - sb.AppendLine(" {"); - sb.AppendLine(" public InterceptsLocationAttribute(int version, string data) { }"); - sb.AppendLine(" }"); - sb.AppendLine("}"); - sb.AppendLine(); - } - - private static void EmitSingleInterceptor( - StringBuilder sb, - string methodName, - ClosedGenericRegistration reg, - int methodIndex, - Dictionary> byImpl) - { - // Use the pre-generated FQNs for closed types from the registration - var serviceFqn = reg.ServiceFqn; - var implFqn = reg.ImplFqn; - - var decorators = byImpl.TryGetValue(reg.ImplDef, out var decos) && decos.Count > 0 - ? decos.Select(ToFqn).ToArray() - : Array.Empty(); - - // Emit the [InterceptsLocation] attribute - sb.AppendLine($" [InterceptsLocation(version: 1, data: {Escape(reg.InterceptsData)})]"); - - // Branch on registration kind to emit the correct signature - switch (reg.Kind) - { - case RegistrationKind.Parameterless: - EmitParameterlessInterceptor(sb, methodName, methodIndex, serviceFqn, implFqn, decorators); - break; - - case RegistrationKind.FactoryTwoTypeParams: - EmitFactoryTwoTypeParamsInterceptor(sb, methodName, reg, methodIndex, serviceFqn, implFqn, decorators); - break; - - case RegistrationKind.FactorySingleTypeParam: - EmitFactorySingleTypeParamInterceptor(sb, methodName, reg, methodIndex, serviceFqn, implFqn, decorators); - break; - - case RegistrationKind.KeyedParameterless: - EmitKeyedParameterlessInterceptor(sb, methodName, reg, methodIndex, serviceFqn, implFqn, decorators); - break; - - case RegistrationKind.KeyedFactoryTwoTypeParams: - EmitKeyedFactoryTwoTypeParamsInterceptor(sb, methodName, reg, methodIndex, serviceFqn, implFqn, decorators); - break; - - case RegistrationKind.KeyedFactorySingleTypeParam: - EmitKeyedFactorySingleTypeParamInterceptor(sb, methodName, reg, methodIndex, serviceFqn, implFqn, decorators); - break; - - case RegistrationKind.InstanceSingleTypeParam: - EmitInstanceSingleTypeParamInterceptor(sb, methodName, reg, methodIndex, serviceFqn, implFqn, decorators); - break; - - case RegistrationKind.KeyedInstanceSingleTypeParam: - EmitKeyedInstanceSingleTypeParamInterceptor(sb, methodName, reg, methodIndex, serviceFqn, implFqn, decorators); - break; - - default: - throw new InvalidOperationException($"Unsupported registration kind: {reg.Kind}"); - } - } - - private static void EmitParameterlessInterceptor( - StringBuilder sb, - string methodName, - int methodIndex, - string serviceFqn, - string implFqn, - string[] decorators) - { - // Emit the method - MUST be generic to match the original signature - sb.AppendLine($" /// Intercepted: ServiceCollectionServiceExtensions.{methodName}<{serviceFqn}, {implFqn}>(IServiceCollection)"); - sb.AppendLine($" internal static IServiceCollection {methodName}_{methodIndex}(this IServiceCollection services)"); - sb.AppendLine(" where TService : class"); - sb.AppendLine(" where TImplementation : class, TService"); - sb.AppendLine(" {"); - - if (decorators.Length > 0) - { - sb.AppendLine(" // Register the undecorated implementation as a keyed service"); - sb.AppendLine($" var key = DecoratorKeys.For(typeof({serviceFqn}), typeof({implFqn}));"); - sb.AppendLine($" services.{AddKeyed(methodName)}<{serviceFqn}, {implFqn}>(key);"); - sb.AppendLine(); - sb.AppendLine(" // Register factory that applies decorators"); - sb.AppendLine($" services.{methodName}<{serviceFqn}>(sp =>"); - sb.AppendLine(" {"); - sb.AppendLine($" var current = ({serviceFqn})sp.GetRequiredKeyedService<{serviceFqn}>(key)!;"); - sb.AppendLine(" // Compose decorators (innermost to outermost)"); - foreach (var deco in decorators) - sb.AppendLine($" current = ({serviceFqn})DecoratorFactory.Create(sp, typeof({serviceFqn}), typeof({deco}), current);"); - sb.AppendLine(" return current;"); - sb.AppendLine(" });"); - sb.AppendLine(" return services;"); - } - else - { - sb.AppendLine(" // No decorators, just register normally"); - sb.AppendLine($" return Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.{methodName}<{serviceFqn}, {implFqn}>(services);"); - } - - sb.AppendLine(" }"); - sb.AppendLine(); - } - - private static void EmitFactoryTwoTypeParamsInterceptor( - StringBuilder sb, - string methodName, - ClosedGenericRegistration reg, - int methodIndex, - string serviceFqn, - string implFqn, - string[] decorators) - { - var factoryParamName = reg.FactoryParameterName ?? "implementationFactory"; - - // Emit the method signature matching AddScoped(services, Func) - sb.AppendLine($" /// Intercepted: ServiceCollectionServiceExtensions.{methodName}<{serviceFqn}, {implFqn}>(IServiceCollection, Func<IServiceProvider, {implFqn}>)"); - sb.AppendLine($" internal static IServiceCollection {methodName}_{methodIndex}(this IServiceCollection services, Func {factoryParamName})"); - sb.AppendLine(" where TService : class"); - sb.AppendLine(" where TImplementation : class, TService"); - sb.AppendLine(" {"); - - if (decorators.Length > 0) - { - sb.AppendLine(" // Register the undecorated implementation as a keyed service with factory"); - sb.AppendLine($" var key = DecoratorKeys.For(typeof({serviceFqn}), typeof({implFqn}));"); - sb.AppendLine($" services.{AddKeyed(methodName)}<{serviceFqn}>(key, (sp, _) => ({serviceFqn}){factoryParamName}(sp));"); - sb.AppendLine(); - sb.AppendLine(" // Register factory that applies decorators"); - sb.AppendLine($" services.{methodName}<{serviceFqn}>(sp =>"); - sb.AppendLine(" {"); - sb.AppendLine($" var current = ({serviceFqn})sp.GetRequiredKeyedService<{serviceFqn}>(key)!;"); - sb.AppendLine(" // Compose decorators (innermost to outermost)"); - foreach (var deco in decorators) - sb.AppendLine($" current = ({serviceFqn})DecoratorFactory.Create(sp, typeof({serviceFqn}), typeof({deco}), current);"); - sb.AppendLine(" return current;"); - sb.AppendLine(" });"); - sb.AppendLine(" return services;"); - } - else - { - sb.AppendLine(" // No decorators, pass through to original method with factory"); - sb.AppendLine($" return Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.{methodName}<{serviceFqn}, {implFqn}>(services, {factoryParamName});"); - } - - sb.AppendLine(" }"); - sb.AppendLine(); - } - - private static void EmitFactorySingleTypeParamInterceptor( - StringBuilder sb, - string methodName, - ClosedGenericRegistration reg, - int methodIndex, - string serviceFqn, - string implFqn, - string[] decorators) - { - var factoryParamName = reg.FactoryParameterName ?? "implementationFactory"; - - // Emit the method signature matching AddScoped(services, Func) - sb.AppendLine($" /// Intercepted: ServiceCollectionServiceExtensions.{methodName}<{serviceFqn}>(IServiceCollection, Func<IServiceProvider, {serviceFqn}>)"); - sb.AppendLine($" internal static IServiceCollection {methodName}_{methodIndex}(this IServiceCollection services, Func {factoryParamName})"); - sb.AppendLine(" where TService : class"); - sb.AppendLine(" {"); - - if (decorators.Length > 0) - { - sb.AppendLine(" // Register the undecorated implementation as a keyed service with factory"); - sb.AppendLine($" var key = DecoratorKeys.For(typeof({serviceFqn}), typeof({implFqn}));"); - sb.AppendLine($" services.{AddKeyed(methodName)}<{serviceFqn}>(key, (sp, _) => {factoryParamName}(sp));"); - sb.AppendLine(); - sb.AppendLine(" // Register factory that applies decorators"); - sb.AppendLine($" services.{methodName}<{serviceFqn}>(sp =>"); - sb.AppendLine(" {"); - sb.AppendLine($" var current = ({serviceFqn})sp.GetRequiredKeyedService<{serviceFqn}>(key)!;"); - sb.AppendLine(" // Compose decorators (innermost to outermost)"); - foreach (var deco in decorators) - sb.AppendLine($" current = ({serviceFqn})DecoratorFactory.Create(sp, typeof({serviceFqn}), typeof({deco}), current);"); - sb.AppendLine(" return current;"); - sb.AppendLine(" });"); - sb.AppendLine(" return services;"); - } - else - { - sb.AppendLine(" // No decorators, pass through to original method with factory"); - sb.AppendLine($" return Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.{methodName}<{serviceFqn}>(services, {factoryParamName});"); - } - - sb.AppendLine(" }"); - sb.AppendLine(); - } - - private static void EmitKeyedParameterlessInterceptor( - StringBuilder sb, - string methodName, - ClosedGenericRegistration reg, - int methodIndex, - string serviceFqn, - string implFqn, - string[] decorators) - { - var serviceKeyParamName = reg.ServiceKeyParameterName ?? "serviceKey"; - - // Emit the method signature matching AddKeyedScoped(services, object? serviceKey) - sb.AppendLine($" /// Intercepted: ServiceCollectionServiceExtensions.{methodName}<{serviceFqn}, {implFqn}>(IServiceCollection, object?)"); - sb.AppendLine($" internal static IServiceCollection {methodName}_{methodIndex}(this IServiceCollection services, object? {serviceKeyParamName})"); - sb.AppendLine(" where TService : class"); - sb.AppendLine(" where TImplementation : class, TService"); - sb.AppendLine(" {"); - - if (decorators.Length > 0) - { - sb.AppendLine(" // Create nested key to avoid circular resolution"); - sb.AppendLine($" var nestedKey = DecoratorKeys.ForKeyed({serviceKeyParamName}, typeof({serviceFqn}), typeof({implFqn}));"); - sb.AppendLine(); - sb.AppendLine(" // Register the undecorated implementation with nested key"); - sb.AppendLine($" services.{methodName}<{serviceFqn}, {implFqn}>(nestedKey);"); - sb.AppendLine(); - sb.AppendLine(" // Register factory with user's key that applies decorators"); - sb.AppendLine($" services.{methodName}<{serviceFqn}>({serviceKeyParamName}, (sp, key) =>"); - sb.AppendLine(" {"); - sb.AppendLine($" var current = ({serviceFqn})sp.GetRequiredKeyedService<{serviceFqn}>(nestedKey)!;"); - sb.AppendLine(" // Compose decorators (innermost to outermost)"); - foreach (var deco in decorators) - sb.AppendLine($" current = ({serviceFqn})DecoratorFactory.Create(sp, typeof({serviceFqn}), typeof({deco}), current);"); - sb.AppendLine(" return current;"); - sb.AppendLine(" });"); - sb.AppendLine(" return services;"); - } - else - { - sb.AppendLine(" // No decorators, just register normally"); - sb.AppendLine($" return Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.{methodName}<{serviceFqn}, {implFqn}>(services, {serviceKeyParamName});"); - } - - sb.AppendLine(" }"); - sb.AppendLine(); - } - - private static void EmitKeyedFactoryTwoTypeParamsInterceptor( - StringBuilder sb, - string methodName, - ClosedGenericRegistration reg, - int methodIndex, - string serviceFqn, - string implFqn, - string[] decorators) - { - var serviceKeyParamName = reg.ServiceKeyParameterName ?? "serviceKey"; - var factoryParamName = reg.FactoryParameterName ?? "implementationFactory"; - - // Emit the method signature matching AddKeyedScoped(services, object? serviceKey, Func) - sb.AppendLine($" /// Intercepted: ServiceCollectionServiceExtensions.{methodName}<{serviceFqn}, {implFqn}>(IServiceCollection, object?, Func<IServiceProvider, object?, {implFqn}>)"); - sb.AppendLine($" internal static IServiceCollection {methodName}_{methodIndex}(this IServiceCollection services, object? {serviceKeyParamName}, Func {factoryParamName})"); - sb.AppendLine(" where TService : class"); - sb.AppendLine(" where TImplementation : class, TService"); - sb.AppendLine(" {"); - - if (decorators.Length > 0) - { - sb.AppendLine(" // Create nested key to avoid circular resolution"); - sb.AppendLine($" var nestedKey = DecoratorKeys.ForKeyed({serviceKeyParamName}, typeof({serviceFqn}), typeof({implFqn}));"); - sb.AppendLine(); - sb.AppendLine(" // Register the undecorated implementation with nested key and factory"); - sb.AppendLine($" services.{methodName}<{serviceFqn}>(nestedKey, (sp, key) => ({serviceFqn}){factoryParamName}(sp, {serviceKeyParamName}));"); - sb.AppendLine(); - sb.AppendLine(" // Register factory with user's key that applies decorators"); - sb.AppendLine($" services.{methodName}<{serviceFqn}>({serviceKeyParamName}, (sp, key) =>"); - sb.AppendLine(" {"); - sb.AppendLine($" var current = ({serviceFqn})sp.GetRequiredKeyedService<{serviceFqn}>(nestedKey)!;"); - sb.AppendLine(" // Compose decorators (innermost to outermost)"); - foreach (var deco in decorators) - sb.AppendLine($" current = ({serviceFqn})DecoratorFactory.Create(sp, typeof({serviceFqn}), typeof({deco}), current);"); - sb.AppendLine(" return current;"); - sb.AppendLine(" });"); - sb.AppendLine(" return services;"); - } - else - { - sb.AppendLine(" // No decorators, pass through to original method with factory"); - sb.AppendLine($" return Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.{methodName}<{serviceFqn}, {implFqn}>(services, {serviceKeyParamName}, {factoryParamName});"); - } - - sb.AppendLine(" }"); - sb.AppendLine(); - } - - private static void EmitKeyedFactorySingleTypeParamInterceptor( - StringBuilder sb, - string methodName, - ClosedGenericRegistration reg, - int methodIndex, - string serviceFqn, - string implFqn, - string[] decorators) - { - var serviceKeyParamName = reg.ServiceKeyParameterName ?? "serviceKey"; - var factoryParamName = reg.FactoryParameterName ?? "implementationFactory"; - - // Emit the method signature matching AddKeyedScoped(services, object? serviceKey, Func) - sb.AppendLine($" /// Intercepted: ServiceCollectionServiceExtensions.{methodName}<{serviceFqn}>(IServiceCollection, object?, Func<IServiceProvider, object?, {serviceFqn}>)"); - sb.AppendLine($" internal static IServiceCollection {methodName}_{methodIndex}(this IServiceCollection services, object? {serviceKeyParamName}, Func {factoryParamName})"); - sb.AppendLine(" where TService : class"); - sb.AppendLine(" {"); - - if (decorators.Length > 0) - { - sb.AppendLine(" // Create nested key to avoid circular resolution"); - sb.AppendLine($" var nestedKey = DecoratorKeys.ForKeyed({serviceKeyParamName}, typeof({serviceFqn}), typeof({implFqn}));"); - sb.AppendLine(); - sb.AppendLine(" // Register the undecorated implementation with nested key and factory"); - sb.AppendLine($" services.{methodName}<{serviceFqn}>(nestedKey, (sp, key) => {factoryParamName}(sp, {serviceKeyParamName}));"); - sb.AppendLine(); - sb.AppendLine(" // Register factory with user's key that applies decorators"); - sb.AppendLine($" services.{methodName}<{serviceFqn}>({serviceKeyParamName}, (sp, key) =>"); - sb.AppendLine(" {"); - sb.AppendLine($" var current = ({serviceFqn})sp.GetRequiredKeyedService<{serviceFqn}>(nestedKey)!;"); - sb.AppendLine(" // Compose decorators (innermost to outermost)"); - foreach (var deco in decorators) - sb.AppendLine($" current = ({serviceFqn})DecoratorFactory.Create(sp, typeof({serviceFqn}), typeof({deco}), current);"); - sb.AppendLine(" return current;"); - sb.AppendLine(" });"); - sb.AppendLine(" return services;"); - } - else - { - sb.AppendLine(" // No decorators, pass through to original method with factory"); - sb.AppendLine($" return Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.{methodName}<{serviceFqn}>(services, {serviceKeyParamName}, {factoryParamName});"); - } - - sb.AppendLine(" }"); - sb.AppendLine(); - } - - private static void EmitInstanceSingleTypeParamInterceptor( - StringBuilder sb, - string methodName, - ClosedGenericRegistration reg, - int methodIndex, - string serviceFqn, - string implFqn, - string[] decorators) - { - var instanceParamName = reg.InstanceParameterName ?? "implementationInstance"; - - // Emit the method signature matching AddSingleton(services, T instance) - sb.AppendLine($" /// Intercepted: ServiceCollectionServiceExtensions.{methodName}<{serviceFqn}>(IServiceCollection, {serviceFqn})"); - sb.AppendLine($" internal static IServiceCollection {methodName}_{methodIndex}(this IServiceCollection services, TService {instanceParamName})"); - sb.AppendLine(" where TService : class"); - sb.AppendLine(" {"); - - if (decorators.Length > 0) - { - sb.AppendLine(" // Register the undecorated instance as a keyed service"); - sb.AppendLine($" var key = DecoratorKeys.For(typeof({serviceFqn}), typeof({implFqn}));"); - sb.AppendLine($" var capturedInstance = ({serviceFqn})(object){instanceParamName};"); - sb.AppendLine($" services.{AddKeyed(methodName)}<{serviceFqn}>(key, capturedInstance);"); - sb.AppendLine(); - sb.AppendLine(" // Register factory that applies decorators around the instance"); - sb.AppendLine($" services.{methodName}<{serviceFqn}>(sp =>"); - sb.AppendLine(" {"); - sb.AppendLine($" var current = ({serviceFqn})sp.GetRequiredKeyedService<{serviceFqn}>(key)!;"); - sb.AppendLine(" // Compose decorators (innermost to outermost)"); - foreach (var deco in decorators) - sb.AppendLine($" current = ({serviceFqn})DecoratorFactory.Create(sp, typeof({serviceFqn}), typeof({deco}), current);"); - sb.AppendLine(" return current;"); - sb.AppendLine(" });"); - sb.AppendLine(" return services;"); - } - else - { - sb.AppendLine(" // No decorators, pass through to original method with instance"); - sb.AppendLine($" return Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.{methodName}<{serviceFqn}>(services, {instanceParamName});"); - } - - sb.AppendLine(" }"); - sb.AppendLine(); - } - - private static void EmitKeyedInstanceSingleTypeParamInterceptor( - StringBuilder sb, - string methodName, - ClosedGenericRegistration reg, - int methodIndex, - string serviceFqn, - string implFqn, - string[] decorators) - { - var serviceKeyParamName = reg.ServiceKeyParameterName ?? "serviceKey"; - var instanceParamName = reg.InstanceParameterName ?? "implementationInstance"; - - // Emit the method signature matching AddKeyedSingleton(services, object? serviceKey, T instance) - sb.AppendLine($" /// Intercepted: ServiceCollectionServiceExtensions.{methodName}<{serviceFqn}>(IServiceCollection, object?, {serviceFqn})"); - sb.AppendLine($" internal static IServiceCollection {methodName}_{methodIndex}(this IServiceCollection services, object? {serviceKeyParamName}, TService {instanceParamName})"); - sb.AppendLine(" where TService : class"); - sb.AppendLine(" {"); + var decorators = decoratorsByImplementation.TryGetValue(reg.ImplDef, out var decos) && decos.Count > 0 + ? decos.Select(ToFqn).ToArray() + : Array.Empty(); - if (decorators.Length > 0) - { - sb.AppendLine(" // Create nested key to avoid circular resolution"); - sb.AppendLine($" var nestedKey = DecoratorKeys.ForKeyed({serviceKeyParamName}, typeof({serviceFqn}), typeof({implFqn}));"); - sb.AppendLine($" var capturedInstance = ({serviceFqn})(object){instanceParamName};"); - sb.AppendLine(); - sb.AppendLine(" // Register the undecorated instance with nested key"); - sb.AppendLine($" services.{methodName}<{serviceFqn}>(nestedKey, capturedInstance);"); - sb.AppendLine(); - sb.AppendLine(" // Register factory with user's key that applies decorators around the instance"); - sb.AppendLine($" services.{methodName}<{serviceFqn}>({serviceKeyParamName}, (sp, key) =>"); - sb.AppendLine(" {"); - sb.AppendLine($" var current = ({serviceFqn})sp.GetRequiredKeyedService<{serviceFqn}>(nestedKey)!;"); - sb.AppendLine(" // Compose decorators (innermost to outermost)"); - foreach (var deco in decorators) - sb.AppendLine($" current = ({serviceFqn})DecoratorFactory.Create(sp, typeof({serviceFqn}), typeof({deco}), current);"); - sb.AppendLine(" return current;"); - sb.AppendLine(" });"); - sb.AppendLine(" return services;"); - } - else - { - sb.AppendLine(" // No decorators, pass through to original method with instance"); - sb.AppendLine($" return Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.{methodName}<{serviceFqn}>(services, {serviceKeyParamName}, {instanceParamName});"); + models.Add(DecoWeaverInterceptorsSources.CreateRegistrationModel( + reg, lifetime, methodIndex++, decorators, Escape(reg.InterceptsData))); + } } - sb.AppendLine(" }"); - sb.AppendLine(); - } - - private static string AddKeyed(string lifetimeMethod) => - lifetimeMethod switch - { - "AddTransient" => "AddKeyedTransient", - "AddScoped" => "AddKeyedScoped", - _ => "AddKeyedSingleton" - }; - - private static void EmitHelpers(StringBuilder sb) - { - sb.AppendLine(" private static class DecoratorKeys"); - sb.AppendLine(" {"); - sb.AppendLine(" public static object For(Type serviceType, Type implementationType)"); - sb.AppendLine(" {"); - sb.AppendLine(" var s = serviceType.AssemblyQualifiedName ?? serviceType.FullName ?? serviceType.Name;"); - sb.AppendLine(" var i = implementationType.AssemblyQualifiedName ?? implementationType.FullName ?? implementationType.Name;"); - sb.AppendLine(" return string.Concat(s, \"|\", i);"); - sb.AppendLine(" }"); - sb.AppendLine(); - sb.AppendLine(" public static object ForKeyed(object? userKey, Type serviceType, Type implementationType)"); - sb.AppendLine(" {"); - sb.AppendLine(" // Return a tuple that preserves the actual key object (not its string representation)"); - sb.AppendLine(" // This ensures distinct object keys create distinct nested keys"); - sb.AppendLine(" return (userKey, serviceType, implementationType);"); - sb.AppendLine(" }"); - sb.AppendLine(" }"); - sb.AppendLine(); - - sb.AppendLine(" private static class DecoratorFactory"); - sb.AppendLine(" {"); - sb.AppendLine(" public static object Create(IServiceProvider sp, Type serviceType, Type decoratorOpenOrClosed, object inner)"); - sb.AppendLine(" {"); - sb.AppendLine(" var closedType = CloseIfNeeded(decoratorOpenOrClosed, serviceType);"); - sb.AppendLine(" return ActivatorUtilities.CreateInstance(sp, closedType, inner)!;"); - sb.AppendLine(" }"); - sb.AppendLine(); - sb.AppendLine(" private static Type CloseIfNeeded(Type t, Type serviceType)"); - sb.AppendLine(" {"); - sb.AppendLine(" if (!t.IsGenericTypeDefinition) return t;"); - sb.AppendLine(" var args = serviceType.IsGenericType ? serviceType.GetGenericArguments() : Type.EmptyTypes;"); - sb.AppendLine(" return t.MakeGenericType(args);"); - sb.AppendLine(" }"); - sb.AppendLine(" }"); - sb.AppendLine(); + // Use the unified template for ALL registrations + return DecoWeaverInterceptorsSources.Generate(models); } private static string ToFqn(TypeDefId t) diff --git a/src/LayeredCraft.DecoWeaver.Generators/Emit/TemplateConstants.cs b/src/LayeredCraft.DecoWeaver.Generators/Emit/TemplateConstants.cs new file mode 100644 index 0000000..bd2bf53 --- /dev/null +++ b/src/LayeredCraft.DecoWeaver.Generators/Emit/TemplateConstants.cs @@ -0,0 +1,13 @@ +// DecoWeaver/Emit/TemplateConstants.cs + +namespace DecoWeaver.Emit; + +/// +/// Constants for Scriban template resource paths. +/// Template names follow the format: "Templates.{FileName}.scriban" +/// +internal static class TemplateConstants +{ + // Unified template - emits entire DecoWeaverInterceptors file + internal const string DecoWeaverInterceptors = "Templates.DecoWeaverInterceptors.scriban"; +} \ No newline at end of file diff --git a/src/LayeredCraft.DecoWeaver.Generators/Emit/TemplateHelper.cs b/src/LayeredCraft.DecoWeaver.Generators/Emit/TemplateHelper.cs new file mode 100644 index 0000000..16f24ea --- /dev/null +++ b/src/LayeredCraft.DecoWeaver.Generators/Emit/TemplateHelper.cs @@ -0,0 +1,82 @@ +// DecoWeaver/Emit/TemplateHelper.cs + +using System.Collections.Concurrent; +using System.Reflection; +using Scriban; + +namespace DecoWeaver.Emit; + +/// +/// Helper class for loading, caching, and rendering Scriban templates from embedded resources. +/// +internal static class TemplateHelper +{ + private static readonly ConcurrentDictionary Cache = new(); + + /// + /// Renders a Scriban template with the provided model. + /// Templates are cached after first load for performance. + /// + /// The type of the model to render + /// Relative path to the template resource (e.g., "Templates.Common.InterceptsLocationAttribute.scriban") + /// The model object to render with the template + /// Rendered template as a string + /// Thrown if template is not found or has parsing errors + internal static string Render(string resourceName, TModel model) + { + var template = Cache.GetOrAdd(resourceName, LoadTemplate); + return template.Render(model, member => member.Name); + } + + /// + /// Loads a Scriban template from embedded resources. + /// + /// Relative path to the template resource (e.g., "Templates.Common.InterceptsLocationAttribute.scriban") + /// Parsed Scriban template ready for rendering + /// Thrown if template is not found or has parsing errors + private static Template LoadTemplate(string relativePath) + { + var assembly = Assembly.GetExecutingAssembly(); + var baseName = assembly.GetName().Name; + + // Convert relative path to resource name format + var templateName = relativePath + .TrimStart('.') + .Replace(Path.DirectorySeparatorChar, '.') + .Replace(Path.AltDirectorySeparatorChar, '.'); + + // Find the manifest resource name that ends with our template name + var manifestTemplateName = assembly + .GetManifestResourceNames() + .FirstOrDefault(x => x.EndsWith(templateName, StringComparison.InvariantCulture)); + + if (string.IsNullOrEmpty(manifestTemplateName)) + { + var availableResources = string.Join(", ", assembly.GetManifestResourceNames()); + throw new InvalidOperationException( + $"Did not find required resource ending in '{templateName}' in assembly '{baseName}'. " + + $"Available resources: {availableResources}"); + } + + // Load the template content + using var stream = assembly.GetManifestResourceStream(manifestTemplateName); + if (stream == null) + { + throw new FileNotFoundException( + $"Template '{relativePath}' not found in embedded resources. " + + $"Manifest resource name: '{manifestTemplateName}'"); + } + + using var reader = new StreamReader(stream); + var templateContent = reader.ReadToEnd(); + + // Parse and validate the template + var template = Template.Parse(templateContent, sourceFilePath: relativePath); + if (!template.HasErrors) return template; + var errors = string.Join("\n", + template.Messages.Select(m => $"{relativePath}({m.Span.Start.Line},{m.Span.Start.Column}): {m.Message}")); + throw new InvalidOperationException( + $"Failed to parse template '{relativePath}':\n{errors}"); + + } +} \ No newline at end of file diff --git a/src/LayeredCraft.DecoWeaver.Generators/LayeredCraft.DecoWeaver.Generators.csproj b/src/LayeredCraft.DecoWeaver.Generators/LayeredCraft.DecoWeaver.Generators.csproj index 2c0a948..335cc3f 100644 --- a/src/LayeredCraft.DecoWeaver.Generators/LayeredCraft.DecoWeaver.Generators.csproj +++ b/src/LayeredCraft.DecoWeaver.Generators/LayeredCraft.DecoWeaver.Generators.csproj @@ -13,19 +13,28 @@ DecoWeaver is a .NET incremental source generator that enables compile-time decorator registration using C# 11+ interceptors. Zero runtime overhead, type-safe decorator chains, and support for closed generic registrations in .NET dependency injection. source-generator;roslyn;dependency-injection;decorator-pattern;interceptors;compile-time;aop;di;ioc;dotnet;csharp;decorators;code-generation;cross-cutting;performance true + true - + + all runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + true diff --git a/src/LayeredCraft.DecoWeaver.Generators/OutputGenerators/DecoWeaverInterceptorsSources.cs b/src/LayeredCraft.DecoWeaver.Generators/OutputGenerators/DecoWeaverInterceptorsSources.cs new file mode 100644 index 0000000..cb81ab9 --- /dev/null +++ b/src/LayeredCraft.DecoWeaver.Generators/OutputGenerators/DecoWeaverInterceptorsSources.cs @@ -0,0 +1,100 @@ +// DecoWeaver/OutputGenerators/DecoWeaverInterceptorsSources.cs + +using DecoWeaver.Emit; +using DecoWeaver.Providers; + +namespace DecoWeaver.OutputGenerators; + +/// +/// Generates the complete DecoWeaverInterceptors source file using the unified Scriban template. +/// Handles all registration kinds that have been migrated to the template-based approach. +/// +internal static class DecoWeaverInterceptorsSources +{ + /// + /// Model for a single registration passed to the template. + /// + internal readonly record struct RegistrationModel( + string method_name, + int method_index, + string service_fqn, + string impl_fqn, + string intercepts_data, + bool has_decorators, + string[] decorators, + bool has_two_type_params, + bool is_keyed, + bool has_factory, + bool has_instance, + string service_key_param, + string factory_param, + string instance_param, + string keyed_method_name); + + /// + /// Generates the complete interceptor file for the given registrations. + /// + internal static string Generate(IEnumerable registrations) + { + var model = new { registrations }; + return TemplateHelper.Render(TemplateConstants.DecoWeaverInterceptors, model); + } + + /// + /// Creates a registration model from a ClosedGenericRegistration. + /// + internal static RegistrationModel CreateRegistrationModel( + ClosedGenericRegistration reg, + string methodName, + int methodIndex, + string[] decorators, + string escapedInterceptsData) + { + return new RegistrationModel( + method_name: methodName, + method_index: methodIndex, + service_fqn: reg.ServiceFqn, + impl_fqn: reg.ImplFqn, + intercepts_data: escapedInterceptsData, + has_decorators: decorators.Length > 0, + decorators: decorators, + has_two_type_params: HasTwoTypeParams(reg.Kind), + is_keyed: IsKeyed(reg.Kind), + has_factory: HasFactory(reg.Kind), + has_instance: HasInstance(reg.Kind), + service_key_param: reg.ServiceKeyParameterName ?? "serviceKey", + factory_param: reg.FactoryParameterName ?? "implementationFactory", + instance_param: reg.InstanceParameterName ?? "implementationInstance", + keyed_method_name: GetKeyedMethodName(methodName)); + } + + private static bool HasTwoTypeParams(RegistrationKind kind) => + kind is RegistrationKind.Parameterless + or RegistrationKind.FactoryTwoTypeParams + or RegistrationKind.KeyedParameterless + or RegistrationKind.KeyedFactoryTwoTypeParams; + + private static bool IsKeyed(RegistrationKind kind) => + kind is RegistrationKind.KeyedParameterless + or RegistrationKind.KeyedFactoryTwoTypeParams + or RegistrationKind.KeyedFactorySingleTypeParam + or RegistrationKind.KeyedInstanceSingleTypeParam; + + private static bool HasFactory(RegistrationKind kind) => + kind is RegistrationKind.FactoryTwoTypeParams + or RegistrationKind.FactorySingleTypeParam + or RegistrationKind.KeyedFactoryTwoTypeParams + or RegistrationKind.KeyedFactorySingleTypeParam; + + private static bool HasInstance(RegistrationKind kind) => + kind is RegistrationKind.InstanceSingleTypeParam + or RegistrationKind.KeyedInstanceSingleTypeParam; + + private static string GetKeyedMethodName(string lifetimeMethod) => + lifetimeMethod switch + { + "AddTransient" => "AddKeyedTransient", + "AddScoped" => "AddKeyedScoped", + _ => "AddKeyedSingleton" + }; +} \ No newline at end of file diff --git a/src/LayeredCraft.DecoWeaver.Generators/Templates/DecoWeaverInterceptors.scriban b/src/LayeredCraft.DecoWeaver.Generators/Templates/DecoWeaverInterceptors.scriban new file mode 100644 index 0000000..1de9f0c --- /dev/null +++ b/src/LayeredCraft.DecoWeaver.Generators/Templates/DecoWeaverInterceptors.scriban @@ -0,0 +1,125 @@ +// +#nullable enable + +namespace System.Runtime.CompilerServices +{ + file sealed class InterceptsLocationAttribute : Attribute + { + public InterceptsLocationAttribute(int version, string data) { } + } +} + +namespace DecoWeaver.Generated +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Runtime.CompilerServices; + using Microsoft.Extensions.DependencyInjection; + + file static class DecoWeaverInterceptors + { +{{- for reg in registrations }} + [InterceptsLocation(version: 1, data: {{ reg.intercepts_data }})] + /// Intercepted: ServiceCollectionServiceExtensions.{{ reg.method_name }}<{{ reg.service_fqn }}{{- if reg.has_two_type_params }}, {{ reg.impl_fqn }}{{- end }}>(IServiceCollection{{- if reg.is_keyed }}, object?{{- end }}{{- if reg.has_factory }}, Func<IServiceProvider{{- if reg.is_keyed }}, object?{{- end }}, {{- if reg.has_two_type_params }} {{ reg.impl_fqn }}{{- else }} {{ reg.service_fqn }}{{- end }}>{{- end }}{{- if reg.has_instance }}, {{ reg.service_fqn }}{{- end }}) + internal static IServiceCollection {{ reg.method_name }}_{{ reg.method_index }}(this IServiceCollection services{{- if reg.is_keyed }}, object? {{ reg.service_key_param }}{{- end }}{{- if reg.has_factory }}, Func {{ reg.factory_param }}{{- end }}{{- if reg.has_instance }}, TService {{ reg.instance_param }}{{- end }}) + where TService : class +{{- if reg.has_two_type_params }} + where TImplementation : class, TService +{{- end }} + { +{{- if reg.has_decorators }} +{{- if reg.is_keyed }} + // Create nested key to avoid circular resolution + var nestedKey = DecoratorKeys.ForKeyed({{ reg.service_key_param }}, typeof({{ reg.service_fqn }}), typeof({{ reg.impl_fqn }})); +{{- if reg.has_instance }} + var capturedInstance = ({{ reg.service_fqn }})(object){{ reg.instance_param }}; +{{ else }} + +{{ end -}} +{{- if reg.has_factory }} + services.{{ reg.method_name }}<{{ reg.service_fqn }}>(nestedKey, (sp, key) => {{- if reg.has_two_type_params }} ({{ reg.service_fqn }}){{- end }}{{ reg.factory_param }}(sp, {{ reg.service_key_param }})); +{{- else if reg.has_instance }} + services.{{ reg.method_name }}<{{ reg.service_fqn }}>(nestedKey, capturedInstance); +{{- else }} + services.{{ reg.method_name }}<{{ reg.service_fqn }}, {{ reg.impl_fqn }}>(nestedKey); +{{- end }} + + services.{{ reg.method_name }}<{{ reg.service_fqn }}>({{ reg.service_key_param }}, (sp, key) => + { + var current = ({{ reg.service_fqn }})sp.GetRequiredKeyedService<{{ reg.service_fqn }}>(nestedKey)!; + // Compose decorators (innermost to outermost) +{{- for decorator in reg.decorators }} + current = ({{ reg.service_fqn }})DecoratorFactory.Create(sp, typeof({{ reg.service_fqn }}), typeof({{ decorator }}), current); +{{- end }} + return current; + }); + return services; +{{- else }} +{{- if reg.has_instance }} + var key = DecoratorKeys.For(typeof({{ reg.service_fqn }}), typeof({{ reg.impl_fqn }})); + var capturedInstance = ({{ reg.service_fqn }})(object){{ reg.instance_param }}; + services.{{ reg.keyed_method_name }}<{{ reg.service_fqn }}>(key, capturedInstance); + +{{- else if reg.has_factory }} + var key = DecoratorKeys.For(typeof({{ reg.service_fqn }}), typeof({{ reg.impl_fqn }})); + services.{{ reg.keyed_method_name }}<{{ reg.service_fqn }}>(key, (sp, _) => {{- if reg.has_two_type_params }} ({{ reg.service_fqn }}){{- end }}{{ reg.factory_param }}(sp)); + +{{- else }} + var key = DecoratorKeys.For(typeof({{ reg.service_fqn }}), typeof({{ reg.impl_fqn }})); + services.{{ reg.keyed_method_name }}<{{ reg.service_fqn }}, {{ reg.impl_fqn }}>(key); + +{{- end }} + services.{{ reg.method_name }}<{{ reg.service_fqn }}>(sp => + { + var current = ({{ reg.service_fqn }})sp.GetRequiredKeyedService<{{ reg.service_fqn }}>(key)!; + // Compose decorators (innermost to outermost) +{{- for decorator in reg.decorators }} + current = ({{ reg.service_fqn }})DecoratorFactory.Create(sp, typeof({{ reg.service_fqn }}), typeof({{ decorator }}), current); +{{- end }} + return current; + }); + return services; +{{- end }} +{{- else }} + return Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.{{ reg.method_name }}<{{ reg.service_fqn }}{{- if reg.has_two_type_params }}, {{ reg.impl_fqn }}{{- end }}>(services{{- if reg.is_keyed }}, {{ reg.service_key_param }}{{- end }}{{- if reg.has_factory }}, {{ reg.factory_param }}{{- end }}{{- if reg.has_instance }}, {{ reg.instance_param }}{{- end }}); +{{- end }} + } + +{{- end }} + + private static class DecoratorKeys + { + public static object For(Type serviceType, Type implementationType) + { + var s = serviceType.AssemblyQualifiedName ?? serviceType.FullName ?? serviceType.Name; + var i = implementationType.AssemblyQualifiedName ?? implementationType.FullName ?? implementationType.Name; + return string.Concat(s, "|", i); + } + + public static object ForKeyed(object? userKey, Type serviceType, Type implementationType) + { + // Return a tuple that preserves the actual key object (not its string representation) + // This ensures distinct object keys create distinct nested keys + return (userKey, serviceType, implementationType); + } + } + + private static class DecoratorFactory + { + public static object Create(IServiceProvider sp, Type serviceType, Type decoratorOpenOrClosed, object inner) + { + var closedType = CloseIfNeeded(decoratorOpenOrClosed, serviceType); + return ActivatorUtilities.CreateInstance(sp, closedType, inner)!; + } + + private static Type CloseIfNeeded(Type t, Type serviceType) + { + if (!t.IsGenericTypeDefinition) return t; + var args = serviceType.IsGenericType ? serviceType.GetGenericArguments() : Type.EmptyTypes; + return t.MakeGenericType(args); + } + } + + } +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.DoNotDecorate_IsolationCheck_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.DoNotDecorate_IsolationCheck_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 294ec9e..bbacceb 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.DoNotDecorate_IsolationCheck_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.DoNotDecorate_IsolationCheck_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -75,4 +72,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.DoNotDecorate_Multiple_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.DoNotDecorate_Multiple_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 4863230..53a6b44 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.DoNotDecorate_Multiple_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.DoNotDecorate_Multiple_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.SqlRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.SqlRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.DoNotDecorate_RemovesAssemblyDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.DoNotDecorate_RemovesAssemblyDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index f893901..10174ce 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.DoNotDecorate_RemovesAssemblyDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.DoNotDecorate_RemovesAssemblyDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_ComplexDependencies_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_ComplexDependencies_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 1e3a413..c054b6e 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_ComplexDependencies_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_ComplexDependencies_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service with factory var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.Repository)); services.AddKeyedScoped>(key, (sp, _) => (global::DecoWeaver.Sample.IRepository)implementationFactory(sp)); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_MultipleDecorators_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_MultipleDecorators_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 836e9d7..7be6ca5 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_MultipleDecorators_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_MultipleDecorators_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service with factory var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedScoped>(key, (sp, _) => (global::DecoWeaver.Sample.IRepository)implementationFactory(sp)); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_SingleDecorator_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_SingleDecorator_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 2610541..83a9a68 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_SingleDecorator_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_SingleDecorator_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service with factory var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedScoped>(key, (sp, _) => (global::DecoWeaver.Sample.IRepository)implementationFactory(sp)); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -75,4 +72,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_Singleton_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_Singleton_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 18017e8..df798a5 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_Singleton_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_Singleton_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddSingleton_0(thi where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service with factory var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.ICache), typeof(global::DecoWeaver.Sample.InMemoryCache)); services.AddKeyedSingleton>(key, (sp, _) => (global::DecoWeaver.Sample.ICache)implementationFactory(sp)); - - // Register factory that applies decorators services.AddSingleton>(sp => { var current = (global::DecoWeaver.Sample.ICache)sp.GetRequiredKeyedService>(key)!; @@ -75,4 +72,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_Transient_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_Transient_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 3e4da68..1b0d388 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_Transient_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.FactoryDelegate_Transient_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddTransient_0(thi where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service with factory var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.Repository)); services.AddKeyedTransient>(key, (sp, _) => (global::DecoWeaver.Sample.IRepository)implementationFactory(sp)); - - // Register factory that applies decorators services.AddTransient>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -75,4 +72,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Generic_MixedSyntax_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Generic_MixedSyntax_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index b253872..cbaae8e 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Generic_MixedSyntax_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Generic_MixedSyntax_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IUserService), typeof(global::DecoWeaver.Sample.UserService)); services.AddKeyedScoped(key); - - // Register factory that applies decorators services.AddScoped(sp => { var current = (global::DecoWeaver.Sample.IUserService)sp.GetRequiredKeyedService(key)!; @@ -77,4 +74,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Generic_MultipleOrdered_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Generic_MultipleOrdered_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 548d87d..49fa6b7 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Generic_MultipleOrdered_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Generic_MultipleOrdered_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IUserService), typeof(global::DecoWeaver.Sample.UserService)); services.AddKeyedScoped(key); - - // Register factory that applies decorators services.AddScoped(sp => { var current = (global::DecoWeaver.Sample.IUserService)sp.GetRequiredKeyedService(key)!; @@ -76,4 +73,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Generic_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Generic_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 99a344e..cf7b8b8 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Generic_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Generic_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IUserService), typeof(global::DecoWeaver.Sample.UserService)); services.AddKeyedScoped(key); - - // Register factory that applies decorators services.AddScoped(sp => { var current = (global::DecoWeaver.Sample.IUserService)sp.GetRequiredKeyedService(key)!; @@ -75,4 +72,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.InstanceRegistration_MultipleDecorators_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.InstanceRegistration_MultipleDecorators_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index e8307cd..ba435db 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.InstanceRegistration_MultipleDecorators_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.InstanceRegistration_MultipleDecorators_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -25,12 +25,9 @@ file static class DecoWeaverInterceptors internal static IServiceCollection AddSingleton_0(this IServiceCollection services, TService implementationInstance) where TService : class { - // Register the undecorated instance as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.SqlRepository)); var capturedInstance = (global::DecoWeaver.Sample.IRepository)(object)implementationInstance; services.AddKeyedSingleton>(key, capturedInstance); - - // Register factory that applies decorators around the instance services.AddSingleton>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -76,4 +73,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.InstanceRegistration_SingleTypeParam_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.InstanceRegistration_SingleTypeParam_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 20ba07e..3ad4a82 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.InstanceRegistration_SingleTypeParam_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.InstanceRegistration_SingleTypeParam_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -25,12 +25,9 @@ file static class DecoWeaverInterceptors internal static IServiceCollection AddSingleton_0(this IServiceCollection services, TService implementationInstance) where TService : class { - // Register the undecorated instance as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.SqlRepository)); var capturedInstance = (global::DecoWeaver.Sample.IRepository)(object)implementationInstance; services.AddKeyedSingleton>(key, capturedInstance); - - // Register factory that applies decorators around the instance services.AddSingleton>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -75,4 +72,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedInstanceRegistration_SingleDecorator_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedInstanceRegistration_SingleDecorator_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 09b6367..35acded 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedInstanceRegistration_SingleDecorator_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedInstanceRegistration_SingleDecorator_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -29,10 +29,8 @@ internal static IServiceCollection AddKeyedSingleton_0(this IServiceCo var nestedKey = DecoratorKeys.ForKeyed(serviceKey, typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.SqlRepository)); var capturedInstance = (global::DecoWeaver.Sample.IRepository)(object)implementationInstance; - // Register the undecorated instance with nested key services.AddKeyedSingleton>(nestedKey, capturedInstance); - // Register factory with user's key that applies decorators around the instance services.AddKeyedSingleton>(serviceKey, (sp, key) => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(nestedKey)!; @@ -77,4 +75,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_FactoryDelegate_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_FactoryDelegate_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index a1312da..72761ee 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_FactoryDelegate_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_FactoryDelegate_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -29,10 +29,9 @@ internal static IServiceCollection AddKeyedScoped_0(t // Create nested key to avoid circular resolution var nestedKey = DecoratorKeys.ForKeyed(serviceKey, typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.ConfigurableRepository)); - // Register the undecorated implementation with nested key and factory + services.AddKeyedScoped>(nestedKey, (sp, key) => (global::DecoWeaver.Sample.IRepository)implementationFactory(sp, serviceKey)); - // Register factory with user's key that applies decorators services.AddKeyedScoped>(serviceKey, (sp, key) => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(nestedKey)!; @@ -77,4 +76,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_IntegerKey_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_IntegerKey_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 0c1e398..8ff1f18 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_IntegerKey_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_IntegerKey_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -29,10 +29,9 @@ internal static IServiceCollection AddKeyedScoped_0(t // Create nested key to avoid circular resolution var nestedKey = DecoratorKeys.ForKeyed(serviceKey, typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DatabaseRepository)); - // Register the undecorated implementation with nested key + services.AddKeyedScoped, global::DecoWeaver.Sample.DatabaseRepository>(nestedKey); - // Register factory with user's key that applies decorators services.AddKeyedScoped>(serviceKey, (sp, key) => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(nestedKey)!; @@ -77,4 +76,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_MultipleDecorators_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_MultipleDecorators_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 5260a51..8c4d378 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_MultipleDecorators_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_MultipleDecorators_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -29,10 +29,9 @@ internal static IServiceCollection AddKeyedScoped_0(t // Create nested key to avoid circular resolution var nestedKey = DecoratorKeys.ForKeyed(serviceKey, typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); - // Register the undecorated implementation with nested key + services.AddKeyedScoped, global::DecoWeaver.Sample.DynamoDbRepository>(nestedKey); - // Register factory with user's key that applies decorators services.AddKeyedScoped>(serviceKey, (sp, key) => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(nestedKey)!; @@ -78,4 +77,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_MultipleKeys_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_MultipleKeys_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index d09029c..b911aaa 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_MultipleKeys_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_MultipleKeys_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -29,10 +29,9 @@ internal static IServiceCollection AddKeyedScoped_0(t // Create nested key to avoid circular resolution var nestedKey = DecoratorKeys.ForKeyed(serviceKey, typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.SqlRepository)); - // Register the undecorated implementation with nested key + services.AddKeyedScoped, global::DecoWeaver.Sample.SqlRepository>(nestedKey); - // Register factory with user's key that applies decorators services.AddKeyedScoped>(serviceKey, (sp, key) => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(nestedKey)!; @@ -42,7 +41,6 @@ internal static IServiceCollection AddKeyedScoped_0(t }); return services; } - [InterceptsLocation(version: 1, data: "fAbqH9Sp6B/0qH0FYFTTaQYBAABQcm9ncmFtLmNz")] /// Intercepted: ServiceCollectionServiceExtensions.AddKeyedScoped<global::DecoWeaver.Sample.IRepository, global::DecoWeaver.Sample.CosmosRepository>(IServiceCollection, object?) internal static IServiceCollection AddKeyedScoped_1(this IServiceCollection services, object? serviceKey) @@ -52,10 +50,9 @@ internal static IServiceCollection AddKeyedScoped_1(t // Create nested key to avoid circular resolution var nestedKey = DecoratorKeys.ForKeyed(serviceKey, typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.CosmosRepository)); - // Register the undecorated implementation with nested key + services.AddKeyedScoped, global::DecoWeaver.Sample.CosmosRepository>(nestedKey); - // Register factory with user's key that applies decorators services.AddKeyedScoped>(serviceKey, (sp, key) => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(nestedKey)!; @@ -100,4 +97,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_SingleDecorator_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_SingleDecorator_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 2451652..2ea5ae2 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_SingleDecorator_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_SingleDecorator_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -29,10 +29,9 @@ internal static IServiceCollection AddKeyedScoped_0(t // Create nested key to avoid circular resolution var nestedKey = DecoratorKeys.ForKeyed(serviceKey, typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.SqlRepository)); - // Register the undecorated implementation with nested key + services.AddKeyedScoped, global::DecoWeaver.Sample.SqlRepository>(nestedKey); - // Register factory with user's key that applies decorators services.AddKeyedScoped>(serviceKey, (sp, key) => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(nestedKey)!; @@ -77,4 +76,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_Transient_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_Transient_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 7816831..468e4f1 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_Transient_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.KeyedService_Transient_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -29,10 +29,9 @@ internal static IServiceCollection AddKeyedTransient_0), typeof(global::DecoWeaver.Sample.MemoryRepository)); - // Register the undecorated implementation with nested key + services.AddKeyedTransient, global::DecoWeaver.Sample.MemoryRepository>(nestedKey); - // Register factory with user's key that applies decorators services.AddKeyedTransient>(serviceKey, (sp, key) => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(nestedKey)!; @@ -77,4 +76,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.MergePrecedence_Deduplication_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.MergePrecedence_Deduplication_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 3085313..ea93b5a 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.MergePrecedence_Deduplication_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.MergePrecedence_Deduplication_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.UserRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.UserRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -41,18 +38,14 @@ internal static IServiceCollection AddScoped_0(this I }); return services; } - [InterceptsLocation(version: 1, data: "n1YVUPREqHtBvOzUa9Rd6AkBAABQcm9ncmFtLmNz")] /// Intercepted: ServiceCollectionServiceExtensions.AddScoped<global::DecoWeaver.Sample.IRepository, global::DecoWeaver.Sample.ProductRepository>(IServiceCollection) internal static IServiceCollection AddScoped_1(this IServiceCollection services) where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.ProductRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.ProductRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -98,4 +91,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.MergePrecedence_SortOrder_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.MergePrecedence_SortOrder_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index ee578e2..dae46a6 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.MergePrecedence_SortOrder_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.MergePrecedence_SortOrder_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.UserRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.UserRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -76,4 +73,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_ConstructorOrderSyntax_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_ConstructorOrderSyntax_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index e48b8e7..80a03ad 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_ConstructorOrderSyntax_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_ConstructorOrderSyntax_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -75,4 +72,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_MixedOrderSyntax_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_MixedOrderSyntax_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 0ce1af2..06035f4 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_MixedOrderSyntax_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_MixedOrderSyntax_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -76,4 +73,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_MultipleDefaultOrder_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_MultipleDefaultOrder_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 65f1318..fd84049 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_MultipleDefaultOrder_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_MultipleDefaultOrder_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -76,4 +73,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_MultipleOrdered_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_MultipleOrdered_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index a1f746f..e028606 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_MultipleOrdered_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_MultipleOrdered_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -41,18 +38,14 @@ internal static IServiceCollection AddScoped_0(this I }); return services; } - [InterceptsLocation(version: 1, data: "kh94cO6krxrz8/UKmI0o2xMBAABQcm9ncmFtLmNz")] /// Intercepted: ServiceCollectionServiceExtensions.AddScoped<global::DecoWeaver.Sample.IRepository, global::DecoWeaver.Sample.DynamoDbRepository>(IServiceCollection) internal static IServiceCollection AddScoped_1(this IServiceCollection services) where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -98,4 +91,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_NonGenericDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_NonGenericDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 012f3d9..9731795 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_NonGenericDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_NonGenericDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -75,4 +72,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 536e6f8..b2763b8 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -40,18 +37,14 @@ internal static IServiceCollection AddScoped_0(this I }); return services; } - [InterceptsLocation(version: 1, data: "jlpBEu7DiUNh219Vtmk6h4kBAABQcm9ncmFtLmNz")] /// Intercepted: ServiceCollectionServiceExtensions.AddScoped<global::DecoWeaver.Sample.IRepository, global::DecoWeaver.Sample.DynamoDbRepository>(IServiceCollection) internal static IServiceCollection AddScoped_1(this IServiceCollection services) where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -96,4 +89,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_ThreeDecorators_GeneratesCorrectNesting_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_ThreeDecorators_GeneratesCorrectNesting_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 29773e5..28b5a8a 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_ThreeDecorators_GeneratesCorrectNesting_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.OpenGeneric_ThreeDecorators_GeneratesCorrectNesting_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -77,4 +74,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.ServiceDecorator_MultipleOrdered_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.ServiceDecorator_MultipleOrdered_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index a1f746f..e028606 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.ServiceDecorator_MultipleOrdered_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.ServiceDecorator_MultipleOrdered_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -41,18 +38,14 @@ internal static IServiceCollection AddScoped_0(this I }); return services; } - [InterceptsLocation(version: 1, data: "kh94cO6krxrz8/UKmI0o2xMBAABQcm9ncmFtLmNz")] /// Intercepted: ServiceCollectionServiceExtensions.AddScoped<global::DecoWeaver.Sample.IRepository, global::DecoWeaver.Sample.DynamoDbRepository>(IServiceCollection) internal static IServiceCollection AddScoped_1(this IServiceCollection services) where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -98,4 +91,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.ServiceDecorator_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.ServiceDecorator_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 536e6f8..b2763b8 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.ServiceDecorator_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.ServiceDecorator_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -40,18 +37,14 @@ internal static IServiceCollection AddScoped_0(this I }); return services; } - [InterceptsLocation(version: 1, data: "jlpBEu7DiUNh219Vtmk6h4kBAABQcm9ncmFtLmNz")] /// Intercepted: ServiceCollectionServiceExtensions.AddScoped<global::DecoWeaver.Sample.IRepository, global::DecoWeaver.Sample.DynamoDbRepository>(IServiceCollection) internal static IServiceCollection AddScoped_1(this IServiceCollection services) where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -96,4 +89,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.ServiceDecorator_SkipAssemblyWithClassLevel_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.ServiceDecorator_SkipAssemblyWithClassLevel_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 7e87dc3..9d10272 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.ServiceDecorator_SkipAssemblyWithClassLevel_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.ServiceDecorator_SkipAssemblyWithClassLevel_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::IRepository), typeof(global::SpecialRepository)); services.AddKeyedScoped, global::SpecialRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::IRepository)sp.GetRequiredKeyedService>(key)!; @@ -75,4 +72,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.ServiceDecorator_WithSkipAssembly_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.ServiceDecorator_WithSkipAssembly_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index f754f95..f5d43cf 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.ServiceDecorator_WithSkipAssembly_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.ServiceDecorator_WithSkipAssembly_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddScoped_0(this I where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedScoped, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddScoped>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -75,4 +72,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Singleton_Generic_MultipleDecorators_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Singleton_Generic_MultipleDecorators_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index fb86d13..0ed9e08 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Singleton_Generic_MultipleDecorators_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Singleton_Generic_MultipleDecorators_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddSingleton_0(thi where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IUserService), typeof(global::DecoWeaver.Sample.UserService)); services.AddKeyedSingleton(key); - - // Register factory that applies decorators services.AddSingleton(sp => { var current = (global::DecoWeaver.Sample.IUserService)sp.GetRequiredKeyedService(key)!; @@ -76,4 +73,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Singleton_Generic_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Singleton_Generic_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 28a09de..35dcb98 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Singleton_Generic_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Singleton_Generic_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddSingleton_0(thi where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IUserService), typeof(global::DecoWeaver.Sample.UserService)); services.AddKeyedSingleton(key); - - // Register factory that applies decorators services.AddSingleton(sp => { var current = (global::DecoWeaver.Sample.IUserService)sp.GetRequiredKeyedService(key)!; @@ -75,4 +72,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Singleton_MultipleDecorators_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Singleton_MultipleDecorators_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 64deb9a..3545149 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Singleton_MultipleDecorators_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Singleton_MultipleDecorators_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddSingleton_0(thi where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedSingleton, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddSingleton>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -76,4 +73,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Singleton_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Singleton_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 5550b37..41e19f7 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Singleton_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Singleton_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddSingleton_0(thi where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedSingleton, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddSingleton>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -75,4 +72,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Transient_Generic_MultipleDecorators_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Transient_Generic_MultipleDecorators_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index dfb203f..3c157b7 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Transient_Generic_MultipleDecorators_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Transient_Generic_MultipleDecorators_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddTransient_0(thi where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IUserService), typeof(global::DecoWeaver.Sample.UserService)); services.AddKeyedTransient(key); - - // Register factory that applies decorators services.AddTransient(sp => { var current = (global::DecoWeaver.Sample.IUserService)sp.GetRequiredKeyedService(key)!; @@ -76,4 +73,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Transient_Generic_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Transient_Generic_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 4967fc6..1fb61f6 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Transient_Generic_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Transient_Generic_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddTransient_0(thi where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IUserService), typeof(global::DecoWeaver.Sample.UserService)); services.AddKeyedTransient(key); - - // Register factory that applies decorators services.AddTransient(sp => { var current = (global::DecoWeaver.Sample.IUserService)sp.GetRequiredKeyedService(key)!; @@ -75,4 +72,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Transient_MultipleDecorators_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Transient_MultipleDecorators_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index 22f4ff1..12147bc 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Transient_MultipleDecorators_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Transient_MultipleDecorators_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddTransient_0(thi where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedTransient, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddTransient>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -76,4 +73,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file diff --git a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Transient_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Transient_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs index c8c4bb9..3806e22 100644 --- a/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Transient_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs +++ b/test/LayeredCraft.DecoWeaver.Generator.Tests/Snapshots/DecoWeaverGeneratorTests.Transient_SingleDecorator_GeneratesCorrectInterceptor_sut=DecoWeaver.DecoWeaverGenerator#DecoWeaver.Interceptors.ClosedGenerics.g.verified.cs @@ -26,11 +26,8 @@ internal static IServiceCollection AddTransient_0(thi where TService : class where TImplementation : class, TService { - // Register the undecorated implementation as a keyed service var key = DecoratorKeys.For(typeof(global::DecoWeaver.Sample.IRepository), typeof(global::DecoWeaver.Sample.DynamoDbRepository)); services.AddKeyedTransient, global::DecoWeaver.Sample.DynamoDbRepository>(key); - - // Register factory that applies decorators services.AddTransient>(sp => { var current = (global::DecoWeaver.Sample.IRepository)sp.GetRequiredKeyedService>(key)!; @@ -75,4 +72,4 @@ private static Type CloseIfNeeded(Type t, Type serviceType) } } -} +} \ No newline at end of file