Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use AssemblyLoadContext for loading the generator plugin and resolve deps in case of netcoreapp #2012

Merged
merged 4 commits into from
Jun 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions TechTalk.SpecFlow.Generator/Plugins/GeneratorPluginLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ namespace TechTalk.SpecFlow.Generator.Plugins
{
public class GeneratorPluginLoader : IGeneratorPluginLoader
{

public IGeneratorPlugin LoadPlugin(PluginDescriptor pluginDescriptor)
{
Assembly pluginAssembly;
Expand All @@ -17,7 +16,7 @@ public IGeneratorPlugin LoadPlugin(PluginDescriptor pluginDescriptor)

#if NETCOREAPP
var absolutePath = Path.GetFullPath(pluginDescriptor.Path);
pluginAssembly = System.Runtime.Loader.AssemblyLoadContext.GetLoadContext(typeof(GeneratorPluginLoader).Assembly).LoadFromAssemblyPath(absolutePath);
pluginAssembly = PluginAssemblyResolver.Load(absolutePath);
#else
pluginAssembly = Assembly.LoadFrom(pluginDescriptor.Path);
#endif
Expand Down
79 changes: 79 additions & 0 deletions TechTalk.SpecFlow.Generator/Plugins/PluginAssemblyResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#if NETCOREAPP

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using Microsoft.Extensions.DependencyModel;
using Microsoft.Extensions.DependencyModel.Resolution;

namespace TechTalk.SpecFlow.Generator.Plugins
{
internal sealed class PluginAssemblyResolver
{
private readonly ICompilationAssemblyResolver _assemblyResolver;
private readonly DependencyContext _dependencyContext;
private readonly AssemblyLoadContext _loadContext;

public Assembly Assembly { get; }

public PluginAssemblyResolver(string path)
{
_loadContext = AssemblyLoadContext.GetLoadContext(typeof(PluginAssemblyResolver).Assembly);
Assembly = _loadContext.LoadFromAssemblyPath(path);
_dependencyContext = DependencyContext.Load(Assembly);

_assemblyResolver = new CompositeCompilationAssemblyResolver(new ICompilationAssemblyResolver[]
{
new AppBaseCompilationAssemblyResolver(Path.GetDirectoryName(path)),
new ReferenceAssemblyPathResolver(),
new PackageCompilationAssemblyResolver()
});

_loadContext.Resolving += OnResolving;
_loadContext.Unloading += OnUnloading;
}

private void OnUnloading(AssemblyLoadContext context)
{
_loadContext.Resolving -= OnResolving;
_loadContext.Unloading -= OnUnloading;
}

private Assembly OnResolving(AssemblyLoadContext context, AssemblyName name)
{
var library = _dependencyContext.RuntimeLibraries.FirstOrDefault(
runtimeLibrary => string.Equals(runtimeLibrary.Name, name.Name, StringComparison.OrdinalIgnoreCase));

if (library != null)
{
var wrapper = new CompilationLibrary(
library.Type,
library.Name,
library.Version,
library.Hash,
library.RuntimeAssemblyGroups.SelectMany(g => g.AssetPaths),
library.Dependencies,
library.Serviceable);

var assemblies = new List<string>();
_assemblyResolver.TryResolveAssemblyPaths(wrapper, assemblies);

if (assemblies.Count > 0)
{
return _loadContext.LoadFromAssemblyPath(assemblies[0]);
}
}

return null;
}

public static Assembly Load(string absolutePath)
{
return new PluginAssemblyResolver(absolutePath).Assembly;
}
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@

<ItemGroup Condition="'$(TargetFramework)' == '$(SpecFlow_Core_Generator_TFM)'">
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.4.1" />
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="1.0.3" />
</ItemGroup>

<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Changes:
Fixes:
+ Empty value for nullable enum should not throw an exception
+ RegEx performance fix in TEHelpers (Table column name validation)
+ Use AssemblyLoadContext for loading the generator plugin in case of netcoreapp


Fixes:
Expand Down