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