Skip to content

Commit

Permalink
Fixed ProviderNotFoundException when referencing providers in referen…
Browse files Browse the repository at this point in the history
…ced packages in projects targeting .NET Core
  • Loading branch information
sweetlandj committed Feb 19, 2018
1 parent e0bc721 commit 064e082
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 12 deletions.
74 changes: 62 additions & 12 deletions Source/Platibus/Config/ReflectionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

using Microsoft.Extensions.DependencyModel;
using Platibus.Diagnostics;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Platibus.Diagnostics;

namespace Platibus.Config
{
Expand All @@ -44,6 +45,48 @@ public ReflectionService(IDiagnosticService diagnosticService)
}

public IEnumerable<Type> FindConcreteSubtypes<TBase>()
{
var appDomain = AppDomain.CurrentDomain;
var assemblyNames = GetAssemblyNames(appDomain);
var subtypes = new List<Type>();
foreach (var assemblyName in assemblyNames)
{
try
{
var assembly = appDomain.GetAssemblies()
.FirstOrDefault(a => a.GetName() == assemblyName)
?? appDomain.Load(assemblyName);

subtypes.AddRange(assembly.GetTypes()
.Where(typeof(TBase).IsAssignableFrom)
.Where(t => !t.IsInterface && !t.IsAbstract));
}
catch (Exception ex)
{
_diagnosticService.Emit(new DiagnosticEventBuilder(this, DiagnosticEventType.TypeLoadFailed)
{
Detail = $"Error loading assembly {assemblyName}",
Exception = ex
}.Build());
}
}
return subtypes;
}

public IEnumerable<AssemblyName> GetAssemblyNames(AppDomain appDomain)
{
return GetDefaultAssemblyNames()
.Union(GetAppDomainBaseDirectoryAssemblyNames(appDomain))
.Distinct(new AssemblyNameEqualityComparer());
}

public IEnumerable<AssemblyName> GetDefaultAssemblyNames()
{
var dependencyContext = DependencyContext.Default;
return dependencyContext?.GetDefaultAssemblyNames() ?? Enumerable.Empty<AssemblyName>();
}

public IEnumerable<AssemblyName> GetAppDomainBaseDirectoryAssemblyNames(AppDomain appDomain)
{
var appDomainBaseDirectory = AppDomain.CurrentDomain.BaseDirectory;
var directories = new[]
Expand All @@ -62,20 +105,13 @@ public IEnumerable<Type> FindConcreteSubtypes<TBase>()
.Where(dir => dir.Directory.Exists)
.SelectMany(x => x.Directory.GetFiles(x.FilenamePattern, SearchOption.TopDirectoryOnly));

var subtypes = new List<Type>();
var assemblyNames = new List<AssemblyName>();
foreach (var assemblyFile in assemblyFiles)
{
try
{
var assemblyName = AssemblyName.GetAssemblyName(assemblyFile.FullName);
var appDomain = AppDomain.CurrentDomain;
var assembly = appDomain.GetAssemblies()
.FirstOrDefault(a => a.GetName() == assemblyName)
?? appDomain.Load(assemblyName);

subtypes.AddRange(assembly.GetTypes()
.Where(typeof(TBase).IsAssignableFrom)
.Where(t => !t.IsInterface && !t.IsAbstract));
assemblyNames.Add(assemblyName);
}
catch (Exception ex)
{
Expand All @@ -84,9 +120,23 @@ public IEnumerable<Type> FindConcreteSubtypes<TBase>()
Detail = $"Error loading assembly file {assemblyFile.FullName}",
Exception = ex
}.Build());
}
}
}

return assemblyNames;
}

private class AssemblyNameEqualityComparer : IEqualityComparer<AssemblyName>
{
public bool Equals(AssemblyName x, AssemblyName y)
{
return Equals(x.Name, y.Name);
}

public int GetHashCode(AssemblyName obj)
{
return obj?.Name.GetHashCode() ?? 0;
}
return subtypes;
}
}
}
1 change: 1 addition & 0 deletions Source/Platibus/Platibus.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="2.0.4"/>
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net452' Or '$(TargetFramework)' == 'net461'">
Expand Down

0 comments on commit 064e082

Please sign in to comment.