Skip to content

Commit

Permalink
Annotate Serilog.Settings.Configuration as not trim-compatible
Browse files Browse the repository at this point in the history
Unfortunately I don't have any good news for this library. It looks like the fundamental
concept, loading arbitrary types by name from arbitrary assemblies, configured by the user
at run-time, is fundamentally incompatible with trimming and AOT.

This at least marks it as such. Supporting a feature set like the one provided
here would likely require a source generator, or build-time code generation phase.
  • Loading branch information
agocke committed Mar 31, 2023
1 parent 60157bd commit ffb2147
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyModel;
Expand Down Expand Up @@ -43,6 +44,8 @@ public static class ConfigurationLoggerConfigurationExtensions
/// <param name="dependencyContext">The dependency context from which sink/enricher packages can be located. If not supplied, the platform
/// default will be used.</param>
/// <returns>An object allowing configuration to continue.</returns>
[RequiresUnreferencedCode(TrimWarningMessages.NotSupportedWhenTrimming)]
[RequiresDynamicCode(TrimWarningMessages.NotSupportedInAot)]
public static LoggerConfiguration Configuration(
this LoggerSettingsConfiguration settingConfiguration,
IConfiguration configuration,
Expand Down Expand Up @@ -74,6 +77,8 @@ public static LoggerConfiguration Configuration(
/// <param name="dependencyContext">The dependency context from which sink/enricher packages can be located. If not supplied, the platform
/// default will be used.</param>
/// <returns>An object allowing configuration to continue.</returns>
[RequiresUnreferencedCode(TrimWarningMessages.NotSupportedWhenTrimming)]
[RequiresDynamicCode(TrimWarningMessages.NotSupportedInAot)]
public static LoggerConfiguration Configuration(
this LoggerSettingsConfiguration settingConfiguration,
IConfiguration configuration,
Expand All @@ -90,6 +95,8 @@ public static LoggerConfiguration Configuration(
/// default will be used.</param>
/// <returns>An object allowing configuration to continue.</returns>
[Obsolete("Use ReadFrom.Configuration(IConfiguration configuration, string sectionName, DependencyContext dependencyContext) instead.")]
[RequiresUnreferencedCode(TrimWarningMessages.NotSupportedWhenTrimming)]
[RequiresDynamicCode(TrimWarningMessages.NotSupportedInAot)]
public static LoggerConfiguration ConfigurationSection(
this LoggerSettingsConfiguration settingConfiguration,
IConfigurationSection configSection,
Expand Down Expand Up @@ -119,6 +126,8 @@ public static LoggerConfiguration ConfigurationSection(
/// <param name="sectionName">A section name for section which contains a Serilog section.</param>
/// <param name="configurationAssemblySource">Defines how the package identifies assemblies to scan for sinks and other types.</param>
/// <returns>An object allowing configuration to continue.</returns>
[RequiresUnreferencedCode(TrimWarningMessages.NotSupportedWhenTrimming)]
[RequiresDynamicCode(TrimWarningMessages.NotSupportedInAot)]
public static LoggerConfiguration Configuration(
this LoggerSettingsConfiguration settingConfiguration,
IConfiguration configuration,
Expand All @@ -143,6 +152,8 @@ public static LoggerConfiguration Configuration(
/// <param name="configuration">A configuration object which contains a Serilog section.</param>
/// <param name="configurationAssemblySource">Defines how the package identifies assemblies to scan for sinks and other types.</param>
/// <returns>An object allowing configuration to continue.</returns>
[RequiresUnreferencedCode(TrimWarningMessages.NotSupportedWhenTrimming)]
[RequiresDynamicCode(TrimWarningMessages.NotSupportedInAot)]
public static LoggerConfiguration Configuration(
this LoggerSettingsConfiguration settingConfiguration,
IConfiguration configuration,
Expand All @@ -158,6 +169,8 @@ public static LoggerConfiguration Configuration(
/// <param name="configurationAssemblySource">Defines how the package identifies assemblies to scan for sinks and other types.</param>
/// <returns>An object allowing configuration to continue.</returns>
[Obsolete("Use ReadFrom.Configuration(IConfiguration configuration, string sectionName, ConfigurationAssemblySource configurationAssemblySource) instead.")]
[RequiresUnreferencedCode(TrimWarningMessages.NotSupportedWhenTrimming)]
[RequiresDynamicCode(TrimWarningMessages.NotSupportedInAot)]
public static LoggerConfiguration ConfigurationSection(
this LoggerSettingsConfiguration settingConfiguration,
IConfigurationSection configSection,
Expand All @@ -179,6 +192,8 @@ public static LoggerConfiguration ConfigurationSection(
/// <param name="sectionName">A section name for section which contains a Serilog section.</param>
/// <param name="assemblies">A collection of assemblies that contains sinks and other types.</param>
/// <returns>An object allowing configuration to continue.</returns>
[RequiresUnreferencedCode(TrimWarningMessages.NotSupportedWhenTrimming)]
[RequiresDynamicCode(TrimWarningMessages.NotSupportedInAot)]
public static LoggerConfiguration Configuration(
this LoggerSettingsConfiguration settingConfiguration,
IConfiguration configuration,
Expand All @@ -199,6 +214,8 @@ public static LoggerConfiguration Configuration(
/// <param name="configuration">A configuration object which contains a Serilog section.</param>
/// <param name="assemblies">A collection of assemblies that contains sinks and other types.</param>
/// <returns>An object allowing configuration to continue.</returns>
[RequiresUnreferencedCode(TrimWarningMessages.NotSupportedWhenTrimming)]
[RequiresDynamicCode(TrimWarningMessages.NotSupportedInAot)]
public static LoggerConfiguration Configuration(
this LoggerSettingsConfiguration settingConfiguration,
IConfiguration configuration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<VersionPrefix>3.3.1</VersionPrefix>
<LangVersion>latest</LangVersion>
<Authors>Serilog Contributors</Authors>
<TargetFrameworks>netstandard2.0;net451;net461</TargetFrameworks>
<TargetFrameworks>net7.0;netstandard2.0;net451;net461</TargetFrameworks>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyName>Serilog.Settings.Configuration</AssemblyName>
Expand All @@ -22,6 +22,8 @@
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<IsTrimmable>true</IsTrimmable>
<EnableAotAnalyzer>true</EnableAotAnalyzer>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
Expand All @@ -15,6 +16,8 @@

namespace Serilog.Settings.Configuration
{
[RequiresUnreferencedCode(TrimWarningMessages.UnboundedReflection)]
[RequiresDynamicCode(TrimWarningMessages.CreatesArraysOfArbitraryTypes)]
class ConfigurationReader : IConfigurationReader
{
const string LevelSwitchNameRegex = @"^\${0,1}[A-Za-z]+[A-Za-z0-9]*$";
Expand Down Expand Up @@ -268,6 +271,8 @@ void ApplyEnrichment(LoggerConfiguration loggerConfiguration)
}
}

[RequiresUnreferencedCode(TrimWarningMessages.UnboundedReflection)]
[RequiresDynamicCode(TrimWarningMessages.CreatesArraysOfArbitraryTypes)]
internal ILookup<string, Dictionary<string, IConfigurationArgumentValue>> GetMethodCalls(IConfigurationSection directive)
{
var children = directive.GetChildren().ToList();
Expand Down Expand Up @@ -301,6 +306,8 @@ static string GetSectionName(IConfigurationSection s)
}
}

[RequiresUnreferencedCode(TrimWarningMessages.UnboundedReflection)]
[RequiresDynamicCode(TrimWarningMessages.CreatesArraysOfArbitraryTypes)]
internal static IConfigurationArgumentValue GetArgumentValue(IConfigurationSection argumentSection, IReadOnlyCollection<Assembly> configurationAssemblies)
{
IConfigurationArgumentValue argumentValue;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
Expand All @@ -10,6 +11,8 @@

namespace Serilog.Settings.Configuration
{
[RequiresUnreferencedCode(TrimWarningMessages.UnboundedReflection)]
[RequiresDynamicCode(TrimWarningMessages.CreatesArraysOfArbitraryTypes)]
class ObjectArgumentValue : IConfigurationArgumentValue
{
readonly IConfigurationSection _section;
Expand Down Expand Up @@ -59,6 +62,7 @@ public object ConvertTo(Type toType, ResolutionContext resolutionContext)
// MS Config binding can work with a limited set of primitive types and collections
return _section.Get(toType);

[RequiresDynamicCode(TrimWarningMessages.CreatesArraysOfArbitraryTypes)]
object CreateArray()
{
var arrayElementType = toType.GetElementType()!;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#if !NET6_0_OR_GREATER

namespace System.Diagnostics.CodeAnalysis
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)]
internal sealed class RequiresDynamicCodeAttribute : Attribute
{
public RequiresDynamicCodeAttribute(string message)
{
Message = message;
}

public string Message { get; }
}
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

#if !NET5_0_OR_GREATER
namespace System.Diagnostics.CodeAnalysis
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)]
internal sealed class RequiresUnreferencedCodeAttribute : Attribute
{
public RequiresUnreferencedCodeAttribute(string message)
{
Message = message;
}

public string Message { get; }
}
}
#endif
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
Expand All @@ -8,6 +9,7 @@

namespace Serilog.Settings.Configuration
{
[RequiresUnreferencedCode(TrimWarningMessages.UnboundedReflection)]
class StringArgumentValue : IConfigurationArgumentValue
{
readonly string _providedValue;
Expand Down
13 changes: 13 additions & 0 deletions src/Serilog.Settings.Configuration/TrimWarningMessages.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

using System.Data;

namespace Serilog
{
internal static class TrimWarningMessages
{
public const string NotSupportedWhenTrimming = "Automatic configuration is not supported when trimming.";
public const string NotSupportedInAot = "Automatic configuration is not supported when AOT compiling.";
public const string UnboundedReflection = "Uses unbounded reflection to load types";
public const string CreatesArraysOfArbitraryTypes = "Creates arrays of arbitrary types";
}
}

0 comments on commit ffb2147

Please sign in to comment.