Skip to content

Commit 8e2d9a9

Browse files
committed
Allow internal types and methods
1 parent 679ce35 commit 8e2d9a9

File tree

5 files changed

+144
-21
lines changed

5 files changed

+144
-21
lines changed

src/Serilog.Settings.Configuration/Settings/Configuration/ConfigurationReader.cs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ void ApplyFilters(LoggerConfiguration loggerConfiguration)
233233
if (filterDirective.GetChildren().Any())
234234
{
235235
var methodCalls = GetMethodCalls(filterDirective);
236-
CallConfigurationMethods(methodCalls, FindFilterConfigurationMethods(_configurationAssemblies), loggerConfiguration.Filter);
236+
CallConfigurationMethods(methodCalls, FindFilterConfigurationMethods(_configurationAssemblies, _resolutionContext.ReaderOptions.AllowInternalTypes, _resolutionContext.ReaderOptions.AllowInternalMethods), loggerConfiguration.Filter);
237237
}
238238
}
239239

@@ -243,7 +243,7 @@ void ApplyDestructuring(LoggerConfiguration loggerConfiguration)
243243
if (destructureDirective.GetChildren().Any())
244244
{
245245
var methodCalls = GetMethodCalls(destructureDirective);
246-
CallConfigurationMethods(methodCalls, FindDestructureConfigurationMethods(_configurationAssemblies), loggerConfiguration.Destructure);
246+
CallConfigurationMethods(methodCalls, FindDestructureConfigurationMethods(_configurationAssemblies, _resolutionContext.ReaderOptions.AllowInternalTypes, _resolutionContext.ReaderOptions.AllowInternalMethods), loggerConfiguration.Destructure);
247247
}
248248
}
249249

@@ -253,7 +253,7 @@ void ApplySinks(LoggerConfiguration loggerConfiguration)
253253
if (writeToDirective.GetChildren().Any())
254254
{
255255
var methodCalls = GetMethodCalls(writeToDirective);
256-
CallConfigurationMethods(methodCalls, FindSinkConfigurationMethods(_configurationAssemblies), loggerConfiguration.WriteTo);
256+
CallConfigurationMethods(methodCalls, FindSinkConfigurationMethods(_configurationAssemblies, _resolutionContext.ReaderOptions.AllowInternalTypes, _resolutionContext.ReaderOptions.AllowInternalMethods), loggerConfiguration.WriteTo);
257257
}
258258
}
259259

@@ -263,20 +263,20 @@ void ApplyAuditSinks(LoggerConfiguration loggerConfiguration)
263263
if (auditToDirective.GetChildren().Any())
264264
{
265265
var methodCalls = GetMethodCalls(auditToDirective);
266-
CallConfigurationMethods(methodCalls, FindAuditSinkConfigurationMethods(_configurationAssemblies), loggerConfiguration.AuditTo);
266+
CallConfigurationMethods(methodCalls, FindAuditSinkConfigurationMethods(_configurationAssemblies, _resolutionContext.ReaderOptions.AllowInternalTypes, _resolutionContext.ReaderOptions.AllowInternalMethods), loggerConfiguration.AuditTo);
267267
}
268268
}
269269

270270
void IConfigurationReader.ApplySinks(LoggerSinkConfiguration loggerSinkConfiguration)
271271
{
272272
var methodCalls = GetMethodCalls(_section);
273-
CallConfigurationMethods(methodCalls, FindSinkConfigurationMethods(_configurationAssemblies), loggerSinkConfiguration);
273+
CallConfigurationMethods(methodCalls, FindSinkConfigurationMethods(_configurationAssemblies, _resolutionContext.ReaderOptions.AllowInternalTypes, _resolutionContext.ReaderOptions.AllowInternalMethods), loggerSinkConfiguration);
274274
}
275275

276276
void IConfigurationReader.ApplyEnrichment(LoggerEnrichmentConfiguration loggerEnrichmentConfiguration)
277277
{
278278
var methodCalls = GetMethodCalls(_section);
279-
CallConfigurationMethods(methodCalls, FindEventEnricherConfigurationMethods(_configurationAssemblies), loggerEnrichmentConfiguration);
279+
CallConfigurationMethods(methodCalls, FindEventEnricherConfigurationMethods(_configurationAssemblies, _resolutionContext.ReaderOptions.AllowInternalTypes, _resolutionContext.ReaderOptions.AllowInternalMethods), loggerEnrichmentConfiguration);
280280
}
281281

282282
void ApplyEnrichment(LoggerConfiguration loggerConfiguration)
@@ -285,7 +285,7 @@ void ApplyEnrichment(LoggerConfiguration loggerConfiguration)
285285
if (enrichDirective.GetChildren().Any())
286286
{
287287
var methodCalls = GetMethodCalls(enrichDirective);
288-
CallConfigurationMethods(methodCalls, FindEventEnricherConfigurationMethods(_configurationAssemblies), loggerConfiguration.Enrich);
288+
CallConfigurationMethods(methodCalls, FindEventEnricherConfigurationMethods(_configurationAssemblies, _resolutionContext.ReaderOptions.AllowInternalTypes, _resolutionContext.ReaderOptions.AllowInternalMethods), loggerConfiguration.Enrich);
289289
}
290290

291291
var propertiesDirective = _section.GetSection("Properties");
@@ -494,51 +494,51 @@ static bool ParameterNameMatches(string actualParameterName, IEnumerable<string>
494494
return suppliedNames.Any(s => ParameterNameMatches(actualParameterName, s));
495495
}
496496

497-
static IReadOnlyCollection<MethodInfo> FindSinkConfigurationMethods(IReadOnlyCollection<Assembly> configurationAssemblies)
497+
static IReadOnlyCollection<MethodInfo> FindSinkConfigurationMethods(IReadOnlyCollection<Assembly> configurationAssemblies, bool allowInternalTypes, bool allowInternalMethods)
498498
{
499-
var found = FindConfigurationExtensionMethods(configurationAssemblies, typeof(LoggerSinkConfiguration));
499+
var found = FindConfigurationExtensionMethods(configurationAssemblies, typeof(LoggerSinkConfiguration), allowInternalTypes, allowInternalMethods);
500500
if (configurationAssemblies.Contains(typeof(LoggerSinkConfiguration).GetTypeInfo().Assembly))
501501
found.AddRange(SurrogateConfigurationMethods.WriteTo);
502502

503503
return found;
504504
}
505505

506-
static IReadOnlyCollection<MethodInfo> FindAuditSinkConfigurationMethods(IReadOnlyCollection<Assembly> configurationAssemblies)
506+
static IReadOnlyCollection<MethodInfo> FindAuditSinkConfigurationMethods(IReadOnlyCollection<Assembly> configurationAssemblies, bool allowInternalTypes, bool allowInternalMethods)
507507
{
508-
var found = FindConfigurationExtensionMethods(configurationAssemblies, typeof(LoggerAuditSinkConfiguration));
508+
var found = FindConfigurationExtensionMethods(configurationAssemblies, typeof(LoggerAuditSinkConfiguration), allowInternalTypes, allowInternalMethods);
509509
if (configurationAssemblies.Contains(typeof(LoggerAuditSinkConfiguration).GetTypeInfo().Assembly))
510510
found.AddRange(SurrogateConfigurationMethods.AuditTo);
511511
return found;
512512
}
513513

514-
static IReadOnlyCollection<MethodInfo> FindFilterConfigurationMethods(IReadOnlyCollection<Assembly> configurationAssemblies)
514+
static IReadOnlyCollection<MethodInfo> FindFilterConfigurationMethods(IReadOnlyCollection<Assembly> configurationAssemblies, bool allowInternalTypes, bool allowInternalMethods)
515515
{
516-
var found = FindConfigurationExtensionMethods(configurationAssemblies, typeof(LoggerFilterConfiguration));
516+
var found = FindConfigurationExtensionMethods(configurationAssemblies, typeof(LoggerFilterConfiguration), allowInternalTypes, allowInternalMethods);
517517
if (configurationAssemblies.Contains(typeof(LoggerFilterConfiguration).GetTypeInfo().Assembly))
518518
found.AddRange(SurrogateConfigurationMethods.Filter);
519519

520520
return found;
521521
}
522522

523-
static IReadOnlyCollection<MethodInfo> FindDestructureConfigurationMethods(IReadOnlyCollection<Assembly> configurationAssemblies)
523+
static IReadOnlyCollection<MethodInfo> FindDestructureConfigurationMethods(IReadOnlyCollection<Assembly> configurationAssemblies, bool allowInternalTypes, bool allowInternalMethods)
524524
{
525-
var found = FindConfigurationExtensionMethods(configurationAssemblies, typeof(LoggerDestructuringConfiguration));
525+
var found = FindConfigurationExtensionMethods(configurationAssemblies, typeof(LoggerDestructuringConfiguration), allowInternalTypes, allowInternalMethods);
526526
if (configurationAssemblies.Contains(typeof(LoggerDestructuringConfiguration).GetTypeInfo().Assembly))
527527
found.AddRange(SurrogateConfigurationMethods.Destructure);
528528

529529
return found;
530530
}
531531

532-
static IReadOnlyCollection<MethodInfo> FindEventEnricherConfigurationMethods(IReadOnlyCollection<Assembly> configurationAssemblies)
532+
static IReadOnlyCollection<MethodInfo> FindEventEnricherConfigurationMethods(IReadOnlyCollection<Assembly> configurationAssemblies, bool allowInternalTypes, bool allowInternalMethods)
533533
{
534-
var found = FindConfigurationExtensionMethods(configurationAssemblies, typeof(LoggerEnrichmentConfiguration));
534+
var found = FindConfigurationExtensionMethods(configurationAssemblies, typeof(LoggerEnrichmentConfiguration), allowInternalTypes, allowInternalMethods);
535535
if (configurationAssemblies.Contains(typeof(LoggerEnrichmentConfiguration).GetTypeInfo().Assembly))
536536
found.AddRange(SurrogateConfigurationMethods.Enrich);
537537

538538
return found;
539539
}
540540

541-
static List<MethodInfo> FindConfigurationExtensionMethods(IReadOnlyCollection<Assembly> configurationAssemblies, Type configType)
541+
static List<MethodInfo> FindConfigurationExtensionMethods(IReadOnlyCollection<Assembly> configurationAssemblies, Type configType, bool allowInternalTypes, bool allowInternalMethods)
542542
{
543543
// ExtensionAttribute can be polyfilled to support extension methods
544544
static bool HasCustomExtensionAttribute(MethodInfo m)
@@ -554,11 +554,11 @@ static bool HasCustomExtensionAttribute(MethodInfo m)
554554
}
555555

556556
return configurationAssemblies
557-
.SelectMany(a => a.ExportedTypes
557+
.SelectMany(a => (allowInternalTypes ? a.GetTypes() : a.ExportedTypes)
558558
.Select(t => t.GetTypeInfo())
559-
.Where(t => t.IsSealed && t.IsAbstract && !t.IsNested))
559+
.Where(t => t.IsSealed && t.IsAbstract && !t.IsNested && (t.IsPublic || allowInternalTypes && !t.IsVisible)))
560560
.SelectMany(t => t.DeclaredMethods)
561-
.Where(m => m.IsStatic && m.IsPublic && (m.IsDefined(typeof(ExtensionAttribute), false) || HasCustomExtensionAttribute(m)))
561+
.Where(m => m.IsStatic && (m.IsPublic || allowInternalMethods && m.IsAssembly) && (m.IsDefined(typeof(ExtensionAttribute), false) || HasCustomExtensionAttribute(m)))
562562
.Where(m => m.GetParameters()[0].ParameterType == configType)
563563
.ToList();
564564
}

src/Serilog.Settings.Configuration/Settings/Configuration/ConfigurationReaderOptions.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ public ConfigurationReaderOptions() : this(dependencyContext: null)
5757
/// </summary>
5858
public IFormatProvider FormatProvider { get; init; } = CultureInfo.InvariantCulture;
5959

60+
/// <summary>
61+
/// Allows to use internal types for extension methods for sink configuration. Defaults to <see langword="false"/>.
62+
/// </summary>
63+
public bool AllowInternalTypes { get; set; }
64+
65+
/// <summary>
66+
/// Allows to use internal extension methods for sink configuration. Defaults to <see langword="false"/>.
67+
/// </summary>
68+
public bool AllowInternalMethods { get; set; }
69+
6070
/// <summary>
6171
/// Called when a log level switch is created while reading the configuration.
6272
/// Log level switches are created either from the <c>Serilog:LevelSwitches</c> section (declared switches) or the <c>Serilog:MinimumLevel:Override</c> section (minimum level override switches).

test/Serilog.Settings.Configuration.Tests/ConfigurationSettingsTests.cs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,87 @@ public void ConfigurationAssembliesFromDllScanning()
119119
Assert.Single(DummyConsoleSink.Emitted);
120120
}
121121

122+
[Fact]
123+
public void ConfigurationAssembliesFromDllScanningWithInternalMethodInPublicClass()
124+
{
125+
var json = """
126+
{
127+
"Serilog": {
128+
"Using": ["TestDummies"],
129+
"WriteTo": ["DummyConsoleInternal"]
130+
}
131+
}
132+
""";
133+
134+
var builder = new ConfigurationBuilder().AddJsonString(json);
135+
var config = builder.Build();
136+
var log = new LoggerConfiguration()
137+
.ReadFrom.Configuration(
138+
configuration: config,
139+
readerOptions: new ConfigurationReaderOptions(ConfigurationAssemblySource.AlwaysScanDllFiles) { AllowInternalMethods = true })
140+
.CreateLogger();
141+
142+
DummyConsoleSink.Emitted.Clear();
143+
144+
log.Write(Some.InformationEvent());
145+
146+
Assert.Single(DummyConsoleSink.Emitted);
147+
}
148+
149+
[Fact]
150+
public void ConfigurationAssembliesFromDllScanningWithPublicMethodInInternalClass()
151+
{
152+
var json = """
153+
{
154+
"Serilog": {
155+
"Using": ["TestDummies"],
156+
"WriteTo": ["DummyConsolePublicInInternal"]
157+
}
158+
}
159+
""";
160+
161+
var builder = new ConfigurationBuilder().AddJsonString(json);
162+
var config = builder.Build();
163+
var log = new LoggerConfiguration()
164+
.ReadFrom.Configuration(
165+
configuration: config,
166+
readerOptions: new ConfigurationReaderOptions(ConfigurationAssemblySource.AlwaysScanDllFiles) { AllowInternalTypes = true })
167+
.CreateLogger();
168+
169+
DummyConsoleSink.Emitted.Clear();
170+
171+
log.Write(Some.InformationEvent());
172+
173+
Assert.Single(DummyConsoleSink.Emitted);
174+
}
175+
176+
[Fact]
177+
public void ConfigurationAssembliesFromDllScanningWithInternalMethodInInternalClass()
178+
{
179+
var json = """
180+
{
181+
"Serilog": {
182+
"Using": ["TestDummies"],
183+
"WriteTo": ["DummyConsoleInternalInInternal"]
184+
}
185+
}
186+
""";
187+
188+
var builder = new ConfigurationBuilder().AddJsonString(json);
189+
var config = builder.Build();
190+
var log = new LoggerConfiguration()
191+
.ReadFrom.Configuration(
192+
configuration: config,
193+
readerOptions: new ConfigurationReaderOptions(ConfigurationAssemblySource.AlwaysScanDllFiles) { AllowInternalTypes = true, AllowInternalMethods = true })
194+
.CreateLogger();
195+
196+
DummyConsoleSink.Emitted.Clear();
197+
198+
log.Write(Some.InformationEvent());
199+
200+
Assert.Single(DummyConsoleSink.Emitted);
201+
}
202+
122203
[Fact]
123204
public void SinksAreConfigured()
124205
{

test/Serilog.Settings.Configuration.Tests/Serilog.Settings.Configuration.approved.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ namespace Serilog.Settings.Configuration
4343
public ConfigurationReaderOptions(Microsoft.Extensions.DependencyModel.DependencyContext dependencyContext) { }
4444
public ConfigurationReaderOptions(Serilog.Settings.Configuration.ConfigurationAssemblySource configurationAssemblySource) { }
4545
public ConfigurationReaderOptions(params System.Reflection.Assembly[] assemblies) { }
46+
public bool AllowInternalMethods { get; set; }
47+
public bool AllowInternalTypes { get; set; }
4648
public System.IFormatProvider FormatProvider { get; init; }
4749
public System.Action<string, Serilog.Core.LoggingLevelSwitch> OnLevelSwitchCreated { get; init; }
4850
public string SectionName { get; init; }

test/TestDummies/DummyLoggerConfigurationExtensions.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,15 @@ public static LoggerConfiguration DummyConsole(
120120
return loggerSinkConfiguration.Sink(new DummyConsoleSink(theme), restrictedToMinimumLevel, levelSwitch);
121121
}
122122

123+
internal static LoggerConfiguration DummyConsoleInternal(
124+
this LoggerSinkConfiguration loggerSinkConfiguration,
125+
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
126+
LoggingLevelSwitch levelSwitch = null,
127+
ConsoleTheme theme = null)
128+
{
129+
return loggerSinkConfiguration.Sink(new DummyConsoleSink(theme), restrictedToMinimumLevel, levelSwitch);
130+
}
131+
123132
public static LoggerConfiguration Dummy(
124133
this LoggerSinkConfiguration loggerSinkConfiguration,
125134
Action<LoggerSinkConfiguration> wrappedSinkAction)
@@ -170,3 +179,24 @@ public static LoggerConfiguration DummyNumbers(this LoggerDestructuringConfigura
170179
});
171180
}
172181
}
182+
183+
internal static class DummyLoggerConfigurationExtensionsInternal
184+
{
185+
public static LoggerConfiguration DummyConsolePublicInInternal(
186+
this LoggerSinkConfiguration loggerSinkConfiguration,
187+
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
188+
LoggingLevelSwitch levelSwitch = null,
189+
ConsoleTheme theme = null)
190+
{
191+
return loggerSinkConfiguration.Sink(new DummyConsoleSink(theme), restrictedToMinimumLevel, levelSwitch);
192+
}
193+
194+
internal static LoggerConfiguration DummyConsoleInternalInInternal(
195+
this LoggerSinkConfiguration loggerSinkConfiguration,
196+
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
197+
LoggingLevelSwitch levelSwitch = null,
198+
ConsoleTheme theme = null)
199+
{
200+
return loggerSinkConfiguration.Sink(new DummyConsoleSink(theme), restrictedToMinimumLevel, levelSwitch);
201+
}
202+
}

0 commit comments

Comments
 (0)