Skip to content

Commit 297a132

Browse files
author
Sergey Komisarchik
committed
DllScanningAssemblyFinder fixes:
- ArgumentNullException fix when BaseDirectory is null - additional paths probing: AppDomainSetup.PrivateBinPath, current assembly location path when BaseDirectory is null
1 parent c8dcb96 commit 297a132

File tree

4 files changed

+131
-5
lines changed

4 files changed

+131
-5
lines changed

src/Serilog.Settings.Configuration/Serilog.Settings.Configuration.csproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<Description>Microsoft.Extensions.Configuration (appsettings.json) support for Serilog.</Description>
@@ -21,6 +21,10 @@
2121
<RootNamespace>Serilog</RootNamespace>
2222
</PropertyGroup>
2323

24+
<PropertyGroup Condition="('$(TargetFramework)' == 'net451') Or ('$(TargetFramework)' == 'net461')">
25+
<DefineConstants>$(DefineConstants);PRIVATE_BIN</DefineConstants>
26+
</PropertyGroup>
27+
2428
<ItemGroup>
2529
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="2.0.4" />
2630
<PackageReference Include="Serilog" Version="2.6.0" />
Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.IO;
34
using System.Linq;
45
using System.Reflection;
56

@@ -9,12 +10,57 @@ sealed class DllScanningAssemblyFinder : AssemblyFinder
910
{
1011
public override IReadOnlyList<AssemblyName> FindAssembliesContainingName(string nameToFind)
1112
{
12-
var query = from outputAssemblyPath in System.IO.Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll")
13-
let assemblyFileName = System.IO.Path.GetFileNameWithoutExtension(outputAssemblyPath)
14-
where IsCaseInsensitiveMatch(assemblyFileName, nameToFind)
15-
select AssemblyName.GetAssemblyName(outputAssemblyPath);
13+
var probeDirs = new List<string>();
14+
15+
if (!string.IsNullOrEmpty(AppDomain.CurrentDomain.BaseDirectory))
16+
{
17+
probeDirs.Add(AppDomain.CurrentDomain.BaseDirectory);
18+
19+
#if PRIVATE_BIN
20+
var privateBinPath = AppDomain.CurrentDomain.SetupInformation.PrivateBinPath;
21+
if (!string.IsNullOrEmpty(privateBinPath))
22+
{
23+
foreach (var path in privateBinPath.Split(';'))
24+
{
25+
if (Path.IsPathRooted(path))
26+
{
27+
probeDirs.Add(path);
28+
}
29+
else
30+
{
31+
probeDirs.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path));
32+
}
33+
}
34+
}
35+
#endif
36+
}
37+
else
38+
{
39+
probeDirs.Add(Path.GetDirectoryName(typeof(AssemblyFinder).Assembly.Location));
40+
}
41+
42+
var query = from probeDir in probeDirs
43+
where Directory.Exists(probeDir)
44+
from outputAssemblyPath in Directory.GetFiles(probeDir, "*.dll")
45+
let assemblyFileName = Path.GetFileNameWithoutExtension(outputAssemblyPath)
46+
where IsCaseInsensitiveMatch(assemblyFileName, nameToFind)
47+
let assemblyName = TryGetAssemblyNameFrom(outputAssemblyPath)
48+
where assemblyName != null
49+
select assemblyName;
1650

1751
return query.ToList().AsReadOnly();
52+
53+
AssemblyName TryGetAssemblyNameFrom(string path)
54+
{
55+
try
56+
{
57+
return AssemblyName.GetAssemblyName(path);
58+
}
59+
catch (BadImageFormatException)
60+
{
61+
return null;
62+
}
63+
}
1864
}
1965
}
2066
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
using System;
2+
using System.IO;
3+
4+
using Xunit;
5+
6+
using Serilog.Settings.Configuration.Assemblies;
7+
8+
namespace Serilog.Settings.Configuration.Tests
9+
{
10+
public class DllScanningAssemblyFinderTests : IDisposable
11+
{
12+
readonly string _privateBinPath;
13+
14+
public DllScanningAssemblyFinderTests()
15+
{
16+
var d1 = GetOrCreateDirectory("bin1");
17+
var d2 = GetOrCreateDirectory("bin2");
18+
var d3 = GetOrCreateDirectory("bin3");
19+
20+
_privateBinPath = $"{d1.Name};{d2.FullName};{d3.Name}";
21+
22+
DirectoryInfo GetOrCreateDirectory(string name)
23+
=> Directory.Exists(name) ? new DirectoryInfo(name) : Directory.CreateDirectory(name);
24+
}
25+
26+
public void Dispose()
27+
{
28+
Directory.Delete("bin1", true);
29+
Directory.Delete("bin2", true);
30+
Directory.Delete("bin3", true);
31+
}
32+
33+
[Fact]
34+
public void ShouldProbeCurrentDirectory()
35+
{
36+
var assemblyNames = new DllScanningAssemblyFinder().FindAssembliesContainingName("testdummies");
37+
Assert.Single(assemblyNames);
38+
}
39+
40+
#if PRIVATE_BIN
41+
[Fact]
42+
public void ShouldProbePrivateBinPath()
43+
{
44+
File.Copy("testdummies.dll", "bin1/customSink1.dll", true);
45+
File.Copy("testdummies.dll", "bin2/customSink2.dll", true);
46+
File.Copy("testdummies.dll", "bin3/thirdpartydependency.dll", true);
47+
48+
var ad = AppDomain.CreateDomain("serilog", null,
49+
new AppDomainSetup
50+
{
51+
ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
52+
PrivateBinPath = _privateBinPath
53+
});
54+
55+
try
56+
{
57+
ad.DoCallBack(DoTestInner);
58+
}
59+
finally
60+
{
61+
AppDomain.Unload(ad);
62+
}
63+
64+
void DoTestInner()
65+
{
66+
var assemblyNames = new DllScanningAssemblyFinder().FindAssembliesContainingName("customSink");
67+
Assert.Equal(2, assemblyNames.Count);
68+
}
69+
}
70+
#endif
71+
}
72+
}

test/Serilog.Settings.Configuration.Tests/Serilog.Settings.Configuration.Tests.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
2020
</PropertyGroup>
2121

22+
<PropertyGroup Condition="'$(TargetFramework)' == 'net452'">
23+
<DefineConstants>$(DefineConstants);PRIVATE_BIN</DefineConstants>
24+
</PropertyGroup>
25+
2226
<ItemGroup>
2327
<ProjectReference Include="..\..\src\Serilog.Settings.Configuration\Serilog.Settings.Configuration.csproj" />
2428
<ProjectReference Include="..\TestDummies\TestDummies.csproj" />

0 commit comments

Comments
 (0)