Skip to content

Commit 561e41e

Browse files
committed
Make sure that single-file apps can find assemblies that contains sinks
Before this commit, when single-file app was detected, the behaviour was to fallback on DLL scanning. But DLL scanning would not find anything for an app published as a single-file, by sheer definition of single-file app! After this commit, an exception is thrown if the app is published as a single-file AND no `Serilog:Using` section is defined in the configuration. The error message explains that either a `Serilog:Using` section must be added or show how to explicitly configure assemblies through the `ConfigurationReaderOptions`.
1 parent 0fc8b57 commit 561e41e

File tree

4 files changed

+22
-38
lines changed

4 files changed

+22
-38
lines changed

src/Serilog.Settings.Configuration/ConfigurationLoggerConfigurationExtensions.cs

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,10 @@ public static LoggerConfiguration ConfigurationSection(
9292
if (settingConfiguration == null) throw new ArgumentNullException(nameof(settingConfiguration));
9393
if (configSection == null) throw new ArgumentNullException(nameof(configSection));
9494

95-
var assemblyFinder = dependencyContext == null
96-
? AssemblyFinder.Auto()
97-
: AssemblyFinder.ForDependencyContext(dependencyContext);
98-
9995
return settingConfiguration.Settings(
10096
new ConfigurationReader(
10197
configSection,
102-
assemblyFinder,
98+
AssemblyFinder.ForDependencyContext(dependencyContext),
10399
configuration: null,
104100
formatProvider: null));
105101
}
@@ -218,23 +214,15 @@ public static LoggerConfiguration Configuration(
218214
{
219215
var configurationReader = readerOptions switch
220216
{
221-
{ ConfigurationAssemblySource: {} } => GetConfigurationReader(configuration, readerOptions, readerOptions.ConfigurationAssemblySource.Value),
217+
{ ConfigurationAssemblySource: {} } => GetConfigurationReader(configuration, readerOptions, AssemblyFinder.ForSource(readerOptions.ConfigurationAssemblySource.Value)),
222218
{ Assemblies: {} } => GetConfigurationReader(configuration, readerOptions, readerOptions.Assemblies),
223-
_ => GetConfigurationReader(configuration, readerOptions ?? new ConfigurationReaderOptions(), readerOptions?.DependencyContext),
219+
_ => GetConfigurationReader(configuration, readerOptions ?? new ConfigurationReaderOptions(), AssemblyFinder.ForDependencyContext(readerOptions?.DependencyContext)),
224220
};
225221
return settingConfiguration.Settings(configurationReader);
226222
}
227223

228-
static ConfigurationReader GetConfigurationReader(IConfiguration configuration, ConfigurationReaderOptions readerOptions, DependencyContext dependencyContext)
229-
{
230-
var assemblyFinder = dependencyContext == null ? AssemblyFinder.Auto() : AssemblyFinder.ForDependencyContext(dependencyContext);
231-
var section = configuration.GetSection(readerOptions.SectionName);
232-
return new ConfigurationReader(section, assemblyFinder, readerOptions.FormatProvider, configuration);
233-
}
234-
235-
static ConfigurationReader GetConfigurationReader(IConfiguration configuration, ConfigurationReaderOptions readerOptions, ConfigurationAssemblySource source)
224+
static ConfigurationReader GetConfigurationReader(IConfiguration configuration, ConfigurationReaderOptions readerOptions, AssemblyFinder assemblyFinder)
236225
{
237-
var assemblyFinder = AssemblyFinder.ForSource(source);
238226
var section = configuration.GetSection(readerOptions.SectionName);
239227
return new ConfigurationReader(section, assemblyFinder, readerOptions.FormatProvider, configuration);
240228
}

src/Serilog.Settings.Configuration/Settings/Configuration/Assemblies/AssemblyFinder.cs

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,43 +5,26 @@ namespace Serilog.Settings.Configuration.Assemblies;
55

66
abstract class AssemblyFinder
77
{
8+
public virtual bool CanFindAssemblies => true;
89
public abstract IReadOnlyList<AssemblyName> FindAssembliesContainingName(string nameToFind);
910

1011
protected static bool IsCaseInsensitiveMatch(string text, string textToFind)
1112
{
1213
return text != null && text.ToLowerInvariant().Contains(textToFind.ToLowerInvariant());
1314
}
1415

15-
public static AssemblyFinder Auto()
16-
{
17-
try
18-
{
19-
// Need to check `Assembly.GetEntryAssembly()` first because
20-
// `DependencyContext.Default` throws an exception when `Assembly.GetEntryAssembly()` returns null
21-
if (Assembly.GetEntryAssembly() != null && DependencyContext.Default != null)
22-
{
23-
return new DependencyContextAssemblyFinder(DependencyContext.Default);
24-
}
25-
}
26-
catch (NotSupportedException) when (typeof(object).Assembly.Location is "") // bundled mode detection
27-
{
28-
}
29-
30-
return new DllScanningAssemblyFinder();
31-
}
32-
3316
public static AssemblyFinder ForSource(ConfigurationAssemblySource configurationAssemblySource)
3417
{
3518
return configurationAssemblySource switch
3619
{
37-
ConfigurationAssemblySource.UseLoadedAssemblies => Auto(),
20+
ConfigurationAssemblySource.UseLoadedAssemblies => new DependencyContextAssemblyFinder(DependencyContext.Default),
3821
ConfigurationAssemblySource.AlwaysScanDllFiles => new DllScanningAssemblyFinder(),
3922
_ => throw new ArgumentOutOfRangeException(nameof(configurationAssemblySource), configurationAssemblySource, null),
4023
};
4124
}
4225

4326
public static AssemblyFinder ForDependencyContext(DependencyContext dependencyContext)
4427
{
45-
return new DependencyContextAssemblyFinder(dependencyContext);
28+
return new DependencyContextAssemblyFinder(dependencyContext ?? DependencyContext.Default);
4629
}
4730
}

src/Serilog.Settings.Configuration/Settings/Configuration/Assemblies/DependencyContextAssemblyFinder.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,16 @@ sealed class DependencyContextAssemblyFinder : AssemblyFinder
99

1010
public DependencyContextAssemblyFinder(DependencyContext dependencyContext)
1111
{
12-
_dependencyContext = dependencyContext ?? throw new ArgumentNullException(nameof(dependencyContext));
12+
_dependencyContext = dependencyContext;
1313
}
1414

15+
public override bool CanFindAssemblies => _dependencyContext != null;
16+
1517
public override IReadOnlyList<AssemblyName> FindAssembliesContainingName(string nameToFind)
1618
{
19+
if (_dependencyContext == null)
20+
return Array.Empty<AssemblyName>();
21+
1722
var query = from library in _dependencyContext.RuntimeLibraries
1823
where IsReferencingSerilog(library)
1924
from assemblyName in library.GetDefaultAssemblyNames(_dependencyContext)

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,13 +363,21 @@ static IReadOnlyCollection<Assembly> LoadConfigurationAssemblies(IConfigurationS
363363
{
364364
if (string.IsNullOrWhiteSpace(simpleName))
365365
throw new InvalidOperationException(
366-
"A zero-length or whitespace assembly name was supplied to a Serilog.Using configuration statement.");
366+
$"A zero-length or whitespace assembly name was supplied to a {usingSection.Path} configuration statement.");
367367

368368
var assembly = Assembly.Load(new AssemblyName(simpleName));
369369
if (!assemblies.ContainsKey(assembly.FullName))
370370
assemblies.Add(assembly.FullName, assembly);
371371
}
372372
}
373+
else if (!assemblyFinder.CanFindAssemblies)
374+
{
375+
var message = $"The application is published as single-file and no {usingSection.Path} configuration section is defined.{Environment.NewLine}" +
376+
$"Either add a {usingSection.Path} section or explicitly specify assemblies that contains sinks and other types through the reader options. For example:{Environment.NewLine}" +
377+
$"var options = new ConfigurationReaderOptions(typeof(ConsoleLoggerConfigurationExtensions).Assembly, typeof(SerilogExpression).Assembly);{Environment.NewLine}" +
378+
"new LoggerConfiguration().ReadFrom.Configuration(configuration, options);";
379+
throw new InvalidOperationException(message);
380+
}
373381

374382
foreach (var assemblyName in assemblyFinder.FindAssembliesContainingName("serilog"))
375383
{

0 commit comments

Comments
 (0)