Skip to content

Commit

Permalink
Merge pull request #159 from skomis-mm/scanbin
Browse files Browse the repository at this point in the history
DllScanningAssemblyFinder fixes (#157, #150, #122, #156)
  • Loading branch information
Sergey Komisarchik authored Jan 7, 2019
2 parents deec80f + cf2bb1b commit 3cf169d
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
<RootNamespace>Serilog</RootNamespace>
</PropertyGroup>

<PropertyGroup Condition="('$(TargetFramework)' == 'net451') Or ('$(TargetFramework)' == 'net461')">
<DefineConstants>$(DefineConstants);PRIVATE_BIN</DefineConstants>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="2.0.4" />
<PackageReference Include="Serilog" Version="2.6.0" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;

Expand All @@ -9,12 +10,57 @@ sealed class DllScanningAssemblyFinder : AssemblyFinder
{
public override IReadOnlyList<AssemblyName> FindAssembliesContainingName(string nameToFind)
{
var query = from outputAssemblyPath in System.IO.Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll")
let assemblyFileName = System.IO.Path.GetFileNameWithoutExtension(outputAssemblyPath)
where IsCaseInsensitiveMatch(assemblyFileName, nameToFind)
select AssemblyName.GetAssemblyName(outputAssemblyPath);
var probeDirs = new List<string>();

if (!string.IsNullOrEmpty(AppDomain.CurrentDomain.BaseDirectory))
{
probeDirs.Add(AppDomain.CurrentDomain.BaseDirectory);

#if PRIVATE_BIN
var privateBinPath = AppDomain.CurrentDomain.SetupInformation.PrivateBinPath;
if (!string.IsNullOrEmpty(privateBinPath))
{
foreach (var path in privateBinPath.Split(';'))
{
if (Path.IsPathRooted(path))
{
probeDirs.Add(path);
}
else
{
probeDirs.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path));
}
}
}
#endif
}
else
{
probeDirs.Add(Path.GetDirectoryName(typeof(AssemblyFinder).Assembly.Location));
}

var query = from probeDir in probeDirs
where Directory.Exists(probeDir)
from outputAssemblyPath in Directory.GetFiles(probeDir, "*.dll")
let assemblyFileName = Path.GetFileNameWithoutExtension(outputAssemblyPath)
where IsCaseInsensitiveMatch(assemblyFileName, nameToFind)
let assemblyName = TryGetAssemblyNameFrom(outputAssemblyPath)
where assemblyName != null
select assemblyName;

return query.ToList().AsReadOnly();

AssemblyName TryGetAssemblyNameFrom(string path)
{
try
{
return AssemblyName.GetAssemblyName(path);
}
catch (BadImageFormatException)
{
return null;
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System;
using System.IO;

using Xunit;

using Serilog.Settings.Configuration.Assemblies;

namespace Serilog.Settings.Configuration.Tests
{
public class DllScanningAssemblyFinderTests : IDisposable
{
const string BinDir1 = "bin1";
const string BinDir2 = "bin2";
const string BinDir3 = "bin3";

readonly string _privateBinPath;

public DllScanningAssemblyFinderTests()
{
var d1 = GetOrCreateDirectory(BinDir1);
var d2 = GetOrCreateDirectory(BinDir2);
var d3 = GetOrCreateDirectory(BinDir3);

_privateBinPath = $"{d1.Name};{d2.FullName};{d3.Name}";

DirectoryInfo GetOrCreateDirectory(string name)
=> Directory.Exists(name) ? new DirectoryInfo(name) : Directory.CreateDirectory(name);
}

public void Dispose()
{
Directory.Delete(BinDir1, true);
Directory.Delete(BinDir2, true);
Directory.Delete(BinDir3, true);
}

[Fact]
public void ShouldProbeCurrentDirectory()
{
var assemblyNames = new DllScanningAssemblyFinder().FindAssembliesContainingName("testdummies");
Assert.Single(assemblyNames);
}

#if PRIVATE_BIN
[Fact]
public void ShouldProbePrivateBinPath()
{
File.Copy("testdummies.dll", $"{BinDir1}/customSink1.dll", true);
File.Copy("testdummies.dll", $"{BinDir2}/customSink2.dll", true);
File.Copy("testdummies.dll", $"{BinDir3}/thirdpartydependency.dll", true);

var ad = AppDomain.CreateDomain("serilog", null,
new AppDomainSetup
{
ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
PrivateBinPath = _privateBinPath
});

try
{
ad.DoCallBack(DoTestInner);
}
finally
{
AppDomain.Unload(ad);
}

void DoTestInner()
{
var assemblyNames = new DllScanningAssemblyFinder().FindAssembliesContainingName("customSink");
Assert.Equal(2, assemblyNames.Count);
}
}
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
</PropertyGroup>

<PropertyGroup Condition="'$(TargetFramework)' == 'net452'">
<DefineConstants>$(DefineConstants);PRIVATE_BIN</DefineConstants>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Serilog.Settings.Configuration\Serilog.Settings.Configuration.csproj" />
<ProjectReference Include="..\TestDummies\TestDummies.csproj" />
Expand Down

0 comments on commit 3cf169d

Please sign in to comment.