Skip to content

Commit 3cf169d

Browse files
author
Sergey Komisarchik
authored
Merge pull request #159 from skomis-mm/scanbin
DllScanningAssemblyFinder fixes (#157, #150, #122, #156)
2 parents deec80f + cf2bb1b commit 3cf169d

File tree

4 files changed

+134
-4
lines changed

4 files changed

+134
-4
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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+
const string BinDir1 = "bin1";
13+
const string BinDir2 = "bin2";
14+
const string BinDir3 = "bin3";
15+
16+
readonly string _privateBinPath;
17+
18+
public DllScanningAssemblyFinderTests()
19+
{
20+
var d1 = GetOrCreateDirectory(BinDir1);
21+
var d2 = GetOrCreateDirectory(BinDir2);
22+
var d3 = GetOrCreateDirectory(BinDir3);
23+
24+
_privateBinPath = $"{d1.Name};{d2.FullName};{d3.Name}";
25+
26+
DirectoryInfo GetOrCreateDirectory(string name)
27+
=> Directory.Exists(name) ? new DirectoryInfo(name) : Directory.CreateDirectory(name);
28+
}
29+
30+
public void Dispose()
31+
{
32+
Directory.Delete(BinDir1, true);
33+
Directory.Delete(BinDir2, true);
34+
Directory.Delete(BinDir3, true);
35+
}
36+
37+
[Fact]
38+
public void ShouldProbeCurrentDirectory()
39+
{
40+
var assemblyNames = new DllScanningAssemblyFinder().FindAssembliesContainingName("testdummies");
41+
Assert.Single(assemblyNames);
42+
}
43+
44+
#if PRIVATE_BIN
45+
[Fact]
46+
public void ShouldProbePrivateBinPath()
47+
{
48+
File.Copy("testdummies.dll", $"{BinDir1}/customSink1.dll", true);
49+
File.Copy("testdummies.dll", $"{BinDir2}/customSink2.dll", true);
50+
File.Copy("testdummies.dll", $"{BinDir3}/thirdpartydependency.dll", true);
51+
52+
var ad = AppDomain.CreateDomain("serilog", null,
53+
new AppDomainSetup
54+
{
55+
ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
56+
PrivateBinPath = _privateBinPath
57+
});
58+
59+
try
60+
{
61+
ad.DoCallBack(DoTestInner);
62+
}
63+
finally
64+
{
65+
AppDomain.Unload(ad);
66+
}
67+
68+
void DoTestInner()
69+
{
70+
var assemblyNames = new DllScanningAssemblyFinder().FindAssembliesContainingName("customSink");
71+
Assert.Equal(2, assemblyNames.Count);
72+
}
73+
}
74+
#endif
75+
}
76+
}

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)