diff --git a/readme.md b/readme.md
index d48346d..4a43d93 100644
--- a/readme.md
+++ b/readme.md
@@ -290,21 +290,6 @@ parameters), you can annotate it with `[ImportingConstructor]` from either NuGet
([System.Composition](http://nuget.org/packages/System.Composition.AttributedModel))
or .NET MEF ([System.ComponentModel.Composition](https://www.nuget.org/packages/System.ComponentModel.Composition)).
-### Customize Generated Class
-
-You can customize the generated class namespace and name with the following
-MSBuild properties:
-
-```xml
-
- MyNamespace
- MyExtensions
-
-```
-
-They default to `Microsoft.Extensions.DependencyInjection` and `AddServicesNoReflectionExtension`
-respectively.
-
# Dogfooding
diff --git a/src/DependencyInjection/DependencyInjection.csproj b/src/DependencyInjection/DependencyInjection.csproj
index 0b9244d..e5b7825 100644
--- a/src/DependencyInjection/DependencyInjection.csproj
+++ b/src/DependencyInjection/DependencyInjection.csproj
@@ -28,7 +28,8 @@
-
+
+
diff --git a/src/DependencyInjection/Devlooped.Extensions.DependencyInjection.props b/src/DependencyInjection/Devlooped.Extensions.DependencyInjection.props
index 2fd7d51..fe31c0c 100644
--- a/src/DependencyInjection/Devlooped.Extensions.DependencyInjection.props
+++ b/src/DependencyInjection/Devlooped.Extensions.DependencyInjection.props
@@ -4,12 +4,10 @@
42.42.42
true
true
-
-
-
-
-
-
+ true
+
+ true
+
\ No newline at end of file
diff --git a/src/DependencyInjection/Devlooped.Extensions.DependencyInjection.targets b/src/DependencyInjection/Devlooped.Extensions.DependencyInjection.targets
index e2489cb..b263965 100644
--- a/src/DependencyInjection/Devlooped.Extensions.DependencyInjection.targets
+++ b/src/DependencyInjection/Devlooped.Extensions.DependencyInjection.targets
@@ -4,8 +4,6 @@
$(IncludeServiceAttribute)
- $(DefineConstants);DDI_ADDSERVICE
- $(DefineConstants);DDI_ADDSERVICES
@@ -13,11 +11,20 @@
-
-
- $(DefineConstants);DDI_ADDSERVICE
- $(DefineConstants);DDI_ADDSERVICES
-
-
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/DependencyInjection/IncrementalGenerator.cs b/src/DependencyInjection/IncrementalGenerator.cs
index b0082f3..dd9ee2d 100644
--- a/src/DependencyInjection/IncrementalGenerator.cs
+++ b/src/DependencyInjection/IncrementalGenerator.cs
@@ -51,14 +51,44 @@ record ServiceRegistration(int Lifetime, TypeSyntax? AssignableTo, string? FullN
public void Initialize(IncrementalGeneratorInitializationContext context)
{
- var types = context.CompilationProvider.SelectMany((x, c) =>
+ var compilation = context.CompilationProvider.Select((compilation, _) =>
{
- var visitor = new TypesVisitor(s => x.IsSymbolAccessible(s), c);
- x.GlobalNamespace.Accept(visitor);
+ // Add missing types as needed since we depend on the static generator potentially and can't
+ // rely on its sources being added.
+ var parse = (CSharpParseOptions)compilation.SyntaxTrees.FirstOrDefault().Options;
+
+ if (compilation.GetTypeByMetadataName("Microsoft.Extensions.DependencyInjection.AddServicesNoReflectionExtension") is null)
+ {
+ compilation = compilation.AddSyntaxTrees(
+ CSharpSyntaxTree.ParseText(ThisAssembly.Resources.AddServicesNoReflectionExtension.Text, parse));
+ }
+
+ if (compilation.GetTypeByMetadataName("Microsoft.Extensions.DependencyInjection.ServiceAttribute") is null)
+ {
+ compilation = compilation.AddSyntaxTrees(
+ CSharpSyntaxTree.ParseText(ThisAssembly.Resources.ServiceAttribute.Text, parse),
+ CSharpSyntaxTree.ParseText(ThisAssembly.Resources.ServiceAttribute_1.Text, parse));
+ }
+
+ return compilation;
+ });
+
+ var types = compilation.Combine(context.AnalyzerConfigOptionsProvider).SelectMany((x, c) =>
+ {
+ (var compilation, var options) = x;
+
+ // We won't add any registrations in this case.
+ if (!options.GlobalOptions.TryGetValue("build_property.AddServicesExtension", out var value) ||
+ !bool.TryParse(value, out var addServices) || !addServices)
+ return Enumerable.Empty();
+
+ var visitor = new TypesVisitor(s => compilation.IsSymbolAccessible(s), c);
+ compilation.GlobalNamespace.Accept(visitor);
+
// Also visit aliased references, which will not become part of the global:: namespace
- foreach (var symbol in x.References
+ foreach (var symbol in compilation.References
.Where(r => !r.Properties.Aliases.IsDefaultOrEmpty)
- .Select(r => x.GetAssemblyOrModuleSymbol(r)))
+ .Select(r => compilation.GetAssemblyOrModuleSymbol(r)))
{
symbol?.Accept(visitor);
}
@@ -152,8 +182,6 @@ bool IsExport(AttributeData attr)
})
.Where(x => x != null);
- var options = context.AnalyzerConfigOptionsProvider.Combine(context.CompilationProvider);
-
// Only requisite is that we define Scoped = 0, Singleton = 1 and Transient = 2.
// This matches https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicelifetime?view=dotnet-plat-ext-6.0#fields
@@ -164,11 +192,18 @@ bool IsExport(AttributeData attr)
.CreateSyntaxProvider(
predicate: static (node, _) => node is InvocationExpressionSyntax invocation && invocation.ArgumentList.Arguments.Count != 0 && GetInvokedMethodName(invocation) == nameof(AddServicesNoReflectionExtension.AddServices),
transform: static (ctx, _) => GetServiceRegistration((InvocationExpressionSyntax)ctx.Node, ctx.SemanticModel))
- .Where(details => details != null)
+ .Combine(context.AnalyzerConfigOptionsProvider)
+ .Where(x =>
+ {
+ (var registration, var options) = x;
+ return options.GlobalOptions.TryGetValue("build_property.AddServicesExtension", out var value) &&
+ bool.TryParse(value, out var addServices) && addServices && registration is not null;
+ })
+ .Select((x, _) => x.Left)
.Collect();
// Project matching service types to register with the given lifetime.
- var conventionServices = types.Combine(methodInvocations.Combine(context.CompilationProvider)).SelectMany((pair, cancellationToken) =>
+ var conventionServices = types.Combine(methodInvocations.Combine(compilation)).SelectMany((pair, cancellationToken) =>
{
var (typeSymbol, (registrations, compilation)) = pair;
var results = ImmutableArray.CreateBuilder();
@@ -196,33 +231,33 @@ bool IsExport(AttributeData attr)
.SelectMany((tuple, _) => ImmutableArray.CreateRange([tuple.Item1, tuple.Item2]))
.SelectMany((items, _) => items.Distinct().ToImmutableArray());
- RegisterServicesOutput(context, finalServices, options);
+ RegisterServicesOutput(context, finalServices, compilation);
}
- void RegisterServicesOutput(IncrementalGeneratorInitializationContext context, IncrementalValuesProvider services, IncrementalValueProvider<(AnalyzerConfigOptionsProvider Left, Compilation Right)> options)
+ void RegisterServicesOutput(IncrementalGeneratorInitializationContext context, IncrementalValuesProvider services, IncrementalValueProvider compilation)
{
context.RegisterImplementationSourceOutput(
- services.Where(x => x!.Lifetime == 0 && x.Key is null).Select((x, _) => new KeyedService(x!.Type, null)).Collect().Combine(options),
+ services.Where(x => x!.Lifetime == 0 && x.Key is null).Select((x, _) => new KeyedService(x!.Type, null)).Collect().Combine(compilation),
(ctx, data) => AddPartial("AddSingleton", ctx, data));
context.RegisterImplementationSourceOutput(
- services.Where(x => x!.Lifetime == 1 && x.Key is null).Select((x, _) => new KeyedService(x!.Type, null)).Collect().Combine(options),
+ services.Where(x => x!.Lifetime == 1 && x.Key is null).Select((x, _) => new KeyedService(x!.Type, null)).Collect().Combine(compilation),
(ctx, data) => AddPartial("AddScoped", ctx, data));
context.RegisterImplementationSourceOutput(
- services.Where(x => x!.Lifetime == 2 && x.Key is null).Select((x, _) => new KeyedService(x!.Type, null)).Collect().Combine(options),
+ services.Where(x => x!.Lifetime == 2 && x.Key is null).Select((x, _) => new KeyedService(x!.Type, null)).Collect().Combine(compilation),
(ctx, data) => AddPartial("AddTransient", ctx, data));
context.RegisterImplementationSourceOutput(
- services.Where(x => x!.Lifetime == 0 && x.Key is not null).Select((x, _) => new KeyedService(x!.Type, x.Key!)).Collect().Combine(options),
+ services.Where(x => x!.Lifetime == 0 && x.Key is not null).Select((x, _) => new KeyedService(x!.Type, x.Key!)).Collect().Combine(compilation),
(ctx, data) => AddPartial("AddKeyedSingleton", ctx, data));
context.RegisterImplementationSourceOutput(
- services.Where(x => x!.Lifetime == 1 && x.Key is not null).Select((x, _) => new KeyedService(x!.Type, x.Key!)).Collect().Combine(options),
+ services.Where(x => x!.Lifetime == 1 && x.Key is not null).Select((x, _) => new KeyedService(x!.Type, x.Key!)).Collect().Combine(compilation),
(ctx, data) => AddPartial("AddKeyedScoped", ctx, data));
context.RegisterImplementationSourceOutput(
- services.Where(x => x!.Lifetime == 2 && x.Key is not null).Select((x, _) => new KeyedService(x!.Type, x.Key!)).Collect().Combine(options),
+ services.Where(x => x!.Lifetime == 2 && x.Key is not null).Select((x, _) => new KeyedService(x!.Type, x.Key!)).Collect().Combine(compilation),
(ctx, data) => AddPartial("AddKeyedTransient", ctx, data));
}
@@ -240,13 +275,22 @@ void RegisterServicesOutput(IncrementalGeneratorInitializationContext context, I
var options = (CSharpParseOptions)invocation.SyntaxTree.Options;
- // NOTE: we need to add the sources that *another* generator emits (the static files)
- // because otherwise all invocations will basically have no semantic info since it wasn't there
- // when the source generations invocations started.
- var compilation = semanticModel.Compilation.AddSyntaxTrees(
- CSharpSyntaxTree.ParseText(ThisAssembly.Resources.ServiceAttribute.Text, options),
- CSharpSyntaxTree.ParseText(ThisAssembly.Resources.ServiceAttribute_1.Text, options),
- CSharpSyntaxTree.ParseText(ThisAssembly.Resources.AddServicesNoReflectionExtension.Text, options));
+ var compilation = semanticModel.Compilation;
+
+ // Add missing types as needed since we depend on the static generator potentially and can't
+ // rely on its sources being added.
+ if (compilation.GetTypeByMetadataName("Microsoft.Extensions.DependencyInjection.AddServicesNoReflectionExtension") is null)
+ {
+ compilation = compilation.AddSyntaxTrees(
+ CSharpSyntaxTree.ParseText(ThisAssembly.Resources.AddServicesNoReflectionExtension.Text, options));
+ }
+
+ if (compilation.GetTypeByMetadataName("Microsoft.Extensions.DependencyInjection.ServiceAttribute") is null)
+ {
+ compilation = compilation.AddSyntaxTrees(
+ CSharpSyntaxTree.ParseText(ThisAssembly.Resources.ServiceAttribute.Text, options),
+ CSharpSyntaxTree.ParseText(ThisAssembly.Resources.ServiceAttribute_1.Text, options));
+ }
var model = compilation.GetSemanticModel(invocation.SyntaxTree);
@@ -292,46 +336,37 @@ void RegisterServicesOutput(IncrementalGeneratorInitializationContext context, I
return null;
}
- void AddPartial(string methodName, SourceProductionContext ctx, (ImmutableArray Types, (AnalyzerConfigOptionsProvider Config, Compilation Compilation) Options) data)
+ void AddPartial(string methodName, SourceProductionContext ctx, (ImmutableArray Types, Compilation Compilation) data)
{
var builder = new StringBuilder()
.AppendLine("// ");
- var rootNs = data.Options.Config.GlobalOptions.TryGetValue("build_property.AddServicesNamespace", out var value) && !string.IsNullOrEmpty(value)
- ? value
- : "Microsoft.Extensions.DependencyInjection";
-
- var className = data.Options.Config.GlobalOptions.TryGetValue("build_property.AddServicesClassName", out value) && !string.IsNullOrEmpty(value) ?
- value : "AddServicesNoReflectionExtension";
-
- foreach (var alias in data.Options.Compilation.References.SelectMany(r => r.Properties.Aliases))
+ foreach (var alias in data.Compilation.References.SelectMany(r => r.Properties.Aliases))
{
builder.AppendLine($"extern alias {alias};");
}
builder.AppendLine(
$$"""
- #if DDI_ADDSERVICES
using Microsoft.Extensions.DependencyInjection.Extensions;
using System;
- namespace {{rootNs}}
+ namespace Microsoft.Extensions.DependencyInjection
{
- static partial class {{className}}
+ static partial class AddServicesNoReflectionExtension
{
static partial void {{methodName}}Services(IServiceCollection services)
{
""");
- AddServices(data.Types.Where(x => x.Key is null).Select(x => x.Type), data.Options.Compilation, methodName, builder);
- AddKeyedServices(data.Types.Where(x => x.Key is not null), data.Options.Compilation, methodName, builder);
+ AddServices(data.Types.Where(x => x.Key is null).Select(x => x.Type), data.Compilation, methodName, builder);
+ AddKeyedServices(data.Types.Where(x => x.Key is not null), data.Compilation, methodName, builder);
builder.AppendLine(
"""
}
}
}
- #endif
""");
ctx.AddSource(methodName + ".g", builder.ToString().Replace("\r\n", "\n").Replace("\n", Environment.NewLine));
diff --git a/src/DependencyInjection/StaticGenerator.cs b/src/DependencyInjection/StaticGenerator.cs
index 1c816a0..0c2f10c 100644
--- a/src/DependencyInjection/StaticGenerator.cs
+++ b/src/DependencyInjection/StaticGenerator.cs
@@ -4,7 +4,6 @@
using System.Text;
using Devlooped.Sponsors;
using Microsoft.CodeAnalysis;
-using Microsoft.Extensions.DependencyInjection;
using static Devlooped.Sponsors.SponsorLink;
namespace Devlooped.Extensions.DependencyInjection;
@@ -12,110 +11,103 @@ namespace Devlooped.Extensions.DependencyInjection;
[Generator(LanguageNames.CSharp)]
public class StaticGenerator : ISourceGenerator
{
- public const string DefaultNamespace = "Microsoft.Extensions.DependencyInjection";
- public const string DefaultAddServicesClass = nameof(AddServicesNoReflectionExtension);
-
public static string AddServicesExtension => ThisAssembly.Resources.AddServicesNoReflectionExtension.Text;
public static string ServiceAttribute => ThisAssembly.Resources.ServiceAttribute.Text;
public static string ServiceAttributeT => ThisAssembly.Resources.ServiceAttribute_1.Text;
- public void Initialize(GeneratorInitializationContext context)
- {
- context.RegisterForPostInitialization(c =>
- {
- c.AddSource("ServiceAttribute.g", ThisAssembly.Resources.ServiceAttribute.Text);
- c.AddSource("ServiceAttribute`1.g", ThisAssembly.Resources.ServiceAttribute_1.Text);
- });
- }
+ public void Initialize(GeneratorInitializationContext context) { }
public void Execute(GeneratorExecutionContext context)
{
- var rootNs = context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AddServicesNamespace", out var value) && !string.IsNullOrEmpty(value)
- ? value : DefaultNamespace;
+ // Non-editor source is added by the MSBuild targets
+ if (!IsEditor)
+ return;
- var className = context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AddServicesClassName", out value) && !string.IsNullOrEmpty(value) ?
- value : DefaultAddServicesClass;
+ var code = ThisAssembly.Resources.AddServicesNoReflectionExtension.Text;
+ var status = Diagnostics.GetOrSetStatus(context.GetStatusOptions());
+ string? remarks = default;
+ string? warn = default;
- var code = ThisAssembly.Resources.AddServicesNoReflectionExtension.Text
- .Replace("namespace " + DefaultNamespace, "namespace " + rootNs)
- .Replace(DefaultAddServicesClass, className);
-
- if (IsEditor)
+ if (status == SponsorStatus.Unknown || status == SponsorStatus.Expired)
{
- var status = Diagnostics.GetOrSetStatus(context.GetStatusOptions());
- string? remarks = default;
- string? warn = default;
+ warn =
+ $"""
+ [Obsolete("{string.Format(CultureInfo.CurrentCulture, Resources.Editor_Disabled, Funding.Product, Funding.HelpUrl)}", false
+ #if NET6_0_OR_GREATER
+ , UrlFormat = "{Funding.HelpUrl}"
+ #endif
+ )]
+ """;
- if (status == SponsorStatus.Unknown || status == SponsorStatus.Expired)
- {
- warn =
- $"""
- [Obsolete("{string.Format(CultureInfo.CurrentCulture, Resources.Editor_Disabled, Funding.Product, Funding.HelpUrl)}", false
- #if NET6_0_OR_GREATER
- , UrlFormat = "{Funding.HelpUrl}"
- #endif
- )]
- """;
+ remarks = Resources.Editor_DisabledRemarks;
+ }
+ else if (status == SponsorStatus.Grace && Diagnostics.TryGet() is { } grace && grace.Properties.TryGetValue(nameof(SponsorStatus.Grace), out var days))
+ {
+ remarks = string.Format(CultureInfo.CurrentCulture, Resources.Editor_GraceRemarks, days);
+ }
- remarks = Resources.Editor_DisabledRemarks;
- }
- else if (status == SponsorStatus.Grace && Diagnostics.TryGet() is { } grace && grace.Properties.TryGetValue(nameof(SponsorStatus.Grace), out var days))
+ if (remarks != null)
+ {
+ // Remove /// and /// LINES from the remarks string
+ var builder = new StringBuilder();
+ foreach (var line in ReadLines(remarks))
{
- remarks = string.Format(CultureInfo.CurrentCulture, Resources.Editor_GraceRemarks, days);
- }
-
- if (remarks != null)
- {
- // Remove /// and /// LINES from the remarks string
- var builder = new StringBuilder();
- foreach (var line in ReadLines(remarks))
- {
- if (line.EndsWith("/// ") || line.EndsWith("/// "))
- continue;
- if (line.TrimStart() is { Length: > 0 } trimmed && trimmed.StartsWith("///"))
- builder.AppendLine(trimmed);
- }
- remarks = builder.AppendLine("///").ToString();
+ if (line.EndsWith("/// ") || line.EndsWith("/// "))
+ continue;
+ if (line.TrimStart() is { Length: > 0 } trimmed && trimmed.StartsWith("///"))
+ builder.AppendLine(trimmed);
}
+ remarks = builder.AppendLine("///").ToString();
+ }
- if (remarks != null || warn != null)
+ if (remarks != null || warn != null)
+ {
+ var builder = new StringBuilder();
+ foreach (var line in ReadLines(code))
{
- var builder = new StringBuilder();
- foreach (var line in ReadLines(code))
+ if (remarks != null && line.EndsWith("/// "))
{
- if (remarks != null && line.EndsWith("/// "))
+ builder.AppendLine(line);
+ // trim the remarks line to remove leading spaces and
+ // replace them with the indenting from the target code line
+ var indent = line.IndexOf("/// ");
+ foreach (var rline in ReadLines(remarks))
{
- builder.AppendLine(line);
- // trim the remarks line to remove leading spaces and
- // replace them with the indenting from the target code line
- var indent = line.IndexOf("/// ");
- foreach (var rline in ReadLines(remarks))
- {
- builder.Append(new string(' ', indent)).AppendLine(rline);
- }
+ builder.Append(new string(' ', indent)).AppendLine(rline);
}
- else if (warn != null && line.EndsWith("[DDIAddServices]"))
- {
- builder.AppendLine(line);
- // trim the remarks line to remove leading spaces and
- // replace them with the indenting from the target code line
- var indent = line.IndexOf("[DDIAddServices]");
- // append indentation and the warning, also splitting lines and trimming start
- foreach (var wline in ReadLines(warn))
- {
- builder.Append(new string(' ', indent)).AppendLine(wline.TrimStart());
- }
- }
- else
+ }
+ else if (warn != null && line.EndsWith("[DDIAddServices]"))
+ {
+ builder.AppendLine(line);
+ // trim the remarks line to remove leading spaces and
+ // replace them with the indenting from the target code line
+ var indent = line.IndexOf("[DDIAddServices]");
+ // append indentation and the warning, also splitting lines and trimming start
+ foreach (var wline in ReadLines(warn))
{
- builder.AppendLine(line);
+ builder.Append(new string(' ', indent)).AppendLine(wline.TrimStart());
}
}
- code = builder.ToString();
+ else
+ {
+ builder.AppendLine(line);
+ }
}
+ code = builder.ToString();
}
- context.AddSource(DefaultAddServicesClass + ".g", code);
+ if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AddServicesExtension", out var value) &&
+ bool.TryParse(value, out var addServices) && addServices)
+ {
+ context.AddSource(nameof(ThisAssembly.Resources.AddServicesNoReflectionExtension) + ".g", code);
+ }
+
+ if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AddServiceAttribute", out value) &&
+ bool.TryParse(value, out var addServiceAttribute) && addServiceAttribute)
+ {
+ context.AddSource("ServiceAttribute.g", ThisAssembly.Resources.ServiceAttribute.Text);
+ context.AddSource("ServiceAttribute`1.g", ThisAssembly.Resources.ServiceAttribute_1.Text);
+ }
}
static IEnumerable ReadLines(string text)
diff --git a/src/DependencyInjection/AddServicesNoReflectionExtension.cs b/src/DependencyInjection/compile/AddServicesNoReflectionExtension.cs
similarity index 98%
rename from src/DependencyInjection/AddServicesNoReflectionExtension.cs
rename to src/DependencyInjection/compile/AddServicesNoReflectionExtension.cs
index a9b00a8..d3141cb 100644
--- a/src/DependencyInjection/AddServicesNoReflectionExtension.cs
+++ b/src/DependencyInjection/compile/AddServicesNoReflectionExtension.cs
@@ -1,8 +1,6 @@
//
-#if DDI_ADDSERVICES
using System;
using System.ComponentModel;
-using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.Extensions.DependencyInjection
{
@@ -124,5 +122,4 @@ public static IServiceCollection AddServices(this IServiceCollection services)
[AttributeUsage(AttributeTargets.Method)]
class DDIAddServicesAttribute : Attribute { }
}
-}
-#endif
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/DependencyInjection/ServiceAttribute.cs b/src/DependencyInjection/compile/ServiceAttribute.cs
similarity index 96%
rename from src/DependencyInjection/ServiceAttribute.cs
rename to src/DependencyInjection/compile/ServiceAttribute.cs
index 0a526d4..96cc264 100644
--- a/src/DependencyInjection/ServiceAttribute.cs
+++ b/src/DependencyInjection/compile/ServiceAttribute.cs
@@ -1,6 +1,5 @@
//
#nullable enable
-#if DDI_ADDSERVICE
using System;
namespace Microsoft.Extensions.DependencyInjection
@@ -21,5 +20,4 @@ public ServiceAttribute(ServiceLifetime lifetime = ServiceLifetime.Singleton) {
///
public ServiceAttribute(object key, ServiceLifetime lifetime = ServiceLifetime.Singleton) { }
}
-}
-#endif
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/DependencyInjection/ServiceAttribute`1.cs b/src/DependencyInjection/compile/ServiceAttribute`1.cs
similarity index 96%
rename from src/DependencyInjection/ServiceAttribute`1.cs
rename to src/DependencyInjection/compile/ServiceAttribute`1.cs
index 4de59fb..b296b48 100644
--- a/src/DependencyInjection/ServiceAttribute`1.cs
+++ b/src/DependencyInjection/compile/ServiceAttribute`1.cs
@@ -1,5 +1,4 @@
//
-#if DDI_ADDSERVICE
using System;
namespace Microsoft.Extensions.DependencyInjection
@@ -18,5 +17,4 @@ partial class ServiceAttribute : Attribute
///
public ServiceAttribute(TKey key, ServiceLifetime lifetime = ServiceLifetime.Singleton) { }
}
-}
-#endif
\ No newline at end of file
+}
\ No newline at end of file