Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add SpecFlow.Autofac from https://github.com/gasparnagy/SpecFlow.Autofac
(#1533) * Add SpecFlow.Autofac from https://github.com/gasparnagy/SpecFlow.Autofac/ * generate NuGet package for SpecFlow.Autofac * fix target framework folder
- Loading branch information
1 parent
d9375b1
commit 01d8c62
Showing
11 changed files
with
308 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
using System; | ||
using Autofac; | ||
using SpecFlow.Autofac; | ||
using TechTalk.SpecFlow; | ||
using TechTalk.SpecFlow.Infrastructure; | ||
using TechTalk.SpecFlow.Plugins; | ||
using TechTalk.SpecFlow.UnitTestProvider; | ||
|
||
[assembly: RuntimePlugin(typeof(AutofacPlugin))] | ||
|
||
namespace SpecFlow.Autofac | ||
{ | ||
using BoDi; | ||
|
||
using TechTalk.SpecFlow; | ||
|
||
public class AutofacPlugin : IRuntimePlugin | ||
{ | ||
private static Object _registrationLock = new Object(); | ||
|
||
public void Initialize(RuntimePluginEvents runtimePluginEvents, RuntimePluginParameters runtimePluginParameters, UnitTestProviderConfiguration unitTestProviderConfiguration) | ||
{ | ||
runtimePluginEvents.CustomizeGlobalDependencies += (sender, args) => | ||
{ | ||
// temporary fix for CustomizeGlobalDependencies called multiple times | ||
// see https://github.com/techtalk/SpecFlow/issues/948 | ||
if (!args.ObjectContainer.IsRegistered<IContainerBuilderFinder>()) | ||
{ | ||
// an extra lock to ensure that there are not two super fast threads re-registering the same stuff | ||
lock (_registrationLock) | ||
{ | ||
if (!args.ObjectContainer.IsRegistered<IContainerBuilderFinder>()) | ||
{ | ||
args.ObjectContainer.RegisterTypeAs<AutofacTestObjectResolver, ITestObjectResolver>(); | ||
args.ObjectContainer.RegisterTypeAs<ContainerBuilderFinder, IContainerBuilderFinder>(); | ||
} | ||
} | ||
// workaround for parallel execution issue - this should be rather a feature in BoDi? | ||
args.ObjectContainer.Resolve<IContainerBuilderFinder>(); | ||
} | ||
}; | ||
|
||
runtimePluginEvents.CustomizeScenarioDependencies += (sender, args) => | ||
{ | ||
args.ObjectContainer.RegisterFactoryAs<IComponentContext>(() => | ||
{ | ||
var containerBuilderFinder = args.ObjectContainer.Resolve<IContainerBuilderFinder>(); | ||
var createScenarioContainerBuilder = containerBuilderFinder.GetCreateScenarioContainerBuilder(); | ||
var containerBuilder = createScenarioContainerBuilder(); | ||
RegisterSpecflowDependecies(args.ObjectContainer, containerBuilder); | ||
var container = containerBuilder.Build(); | ||
return container.BeginLifetimeScope(); | ||
}); | ||
}; | ||
} | ||
|
||
/// <summary> | ||
/// Fix for https://github.com/gasparnagy/SpecFlow.Autofac/issues/11 Cannot resolve ScenarioInfo | ||
/// Extracted from | ||
/// https://github.com/techtalk/SpecFlow/blob/master/TechTalk.SpecFlow/Infrastructure/ITestObjectResolver.cs | ||
/// The test objects might be dependent on particular SpecFlow infrastructure, therefore the implemented | ||
/// resolution logic should support resolving the following objects (from the provided SpecFlow container): | ||
/// <see cref="ScenarioContext" />, <see cref="FeatureContext" />, <see cref="TestThreadContext" /> and | ||
/// <see cref="IObjectContainer" /> (to be able to resolve any other SpecFlow infrastucture). So basically | ||
/// the resolution of these classes has to be forwarded to the original container. | ||
/// </summary> | ||
/// <param name="objectContainer">SpecFlow DI container.</param> | ||
/// <param name="containerBuilder">Autofac ContainerBuilder.</param> | ||
private void RegisterSpecflowDependecies( | ||
IObjectContainer objectContainer, | ||
global::Autofac.ContainerBuilder containerBuilder) | ||
{ | ||
containerBuilder.Register(ctx => objectContainer).As<IObjectContainer>(); | ||
containerBuilder.Register( | ||
ctx => | ||
{ | ||
var specflowContainer = ctx.Resolve<IObjectContainer>(); | ||
var scenarioContext = specflowContainer.Resolve<ScenarioContext>(); | ||
return scenarioContext; | ||
}).As<ScenarioContext>(); | ||
containerBuilder.Register( | ||
ctx => | ||
{ | ||
var specflowContainer = ctx.Resolve<IObjectContainer>(); | ||
var scenarioContext = specflowContainer.Resolve<FeatureContext>(); | ||
return scenarioContext; | ||
}).As<FeatureContext>(); | ||
containerBuilder.Register( | ||
ctx => | ||
{ | ||
var specflowContainer = ctx.Resolve<IObjectContainer>(); | ||
var scenarioContext = specflowContainer.Resolve<TestThreadContext>(); | ||
return scenarioContext; | ||
}).As<TestThreadContext>(); | ||
} | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
Plugins/SpecFlow.Autofac.SpecFlowPlugin/AutofacTestObjectResolver.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using System; | ||
using Autofac; | ||
using BoDi; | ||
using TechTalk.SpecFlow.Infrastructure; | ||
|
||
namespace SpecFlow.Autofac | ||
{ | ||
public class AutofacTestObjectResolver : ITestObjectResolver | ||
{ | ||
public object ResolveBindingInstance(Type bindingType, IObjectContainer scenarioContainer) | ||
{ | ||
var componentContext = scenarioContainer.Resolve<IComponentContext>(); | ||
return componentContext.Resolve(bindingType); | ||
} | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
Plugins/SpecFlow.Autofac.SpecFlowPlugin/BindingRegistryExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Reflection; | ||
using TechTalk.SpecFlow.Bindings; | ||
using TechTalk.SpecFlow.Bindings.Reflection; | ||
|
||
namespace SpecFlow.Autofac | ||
{ | ||
public static class BindingRegistryExtensions | ||
{ | ||
public static IEnumerable<IBindingType> GetBindingTypes(this IBindingRegistry bindingRegistry) | ||
{ | ||
return bindingRegistry.GetStepDefinitions().Cast<IBinding>() | ||
.Concat(bindingRegistry.GetHooks().Cast<IBinding>()) | ||
.Concat(bindingRegistry.GetStepTransformations()) | ||
.Select(b => b.Method.Type) | ||
.Distinct(); | ||
} | ||
|
||
public static IEnumerable<Assembly> GetBindingAssemblies(this IBindingRegistry bindingRegistry) | ||
{ | ||
return bindingRegistry.GetBindingTypes().OfType<RuntimeBindingType>() | ||
.Select(t => t.Type.Assembly) | ||
.Distinct(); | ||
} | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
Plugins/SpecFlow.Autofac.SpecFlowPlugin/ContainerBuilderFinder.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Reflection; | ||
using Autofac; | ||
using TechTalk.SpecFlow.Bindings; | ||
|
||
namespace SpecFlow.Autofac | ||
{ | ||
public class ContainerBuilderFinder : IContainerBuilderFinder | ||
{ | ||
private readonly IBindingRegistry bindingRegistry; | ||
private readonly Lazy<Func<ContainerBuilder>> createScenarioContainerBuilder; | ||
|
||
public ContainerBuilderFinder(IBindingRegistry bindingRegistry) | ||
{ | ||
this.bindingRegistry = bindingRegistry; | ||
createScenarioContainerBuilder = new Lazy<Func<ContainerBuilder>>(FindCreateScenarioContainerBuilder, true); | ||
} | ||
|
||
public Func<ContainerBuilder> GetCreateScenarioContainerBuilder() | ||
{ | ||
var builder = createScenarioContainerBuilder.Value; | ||
if (builder == null) | ||
throw new Exception("Unable to find scenario dependencies! Mark a static method that returns a ContainerBuilder with [ScenarioDependencies]!"); | ||
return builder; | ||
} | ||
|
||
protected virtual Func<ContainerBuilder> FindCreateScenarioContainerBuilder() | ||
{ | ||
var assemblies = bindingRegistry.GetBindingAssemblies(); | ||
foreach (var assembly in assemblies) | ||
{ | ||
foreach (var type in assembly.GetTypes()) | ||
{ | ||
foreach (var methodInfo in type.GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public).Where(m => Attribute.IsDefined((MemberInfo) m, typeof(ScenarioDependenciesAttribute)))) | ||
{ | ||
return () => (ContainerBuilder)methodInfo.Invoke(null, null); | ||
} | ||
} | ||
} | ||
return null; | ||
|
||
//return (assemblies | ||
// .SelectMany(assembly => assembly.GetTypes(), (_, type) => type) | ||
// .SelectMany( | ||
// type => type.GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public).Where(m => Attribute.IsDefined(m, typeof (ScenarioDependenciesAttribute))), | ||
// (_, methodInfo) => (Func<ContainerBuilder>) (() => (ContainerBuilder) methodInfo.Invoke(null, null)))).FirstOrDefault(); | ||
} | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
Plugins/SpecFlow.Autofac.SpecFlowPlugin/IContainerBuilderFinder.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using System; | ||
using Autofac; | ||
|
||
namespace SpecFlow.Autofac | ||
{ | ||
public interface IContainerBuilderFinder | ||
{ | ||
Func<ContainerBuilder> GetCreateScenarioContainerBuilder(); | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
Plugins/SpecFlow.Autofac.SpecFlowPlugin/ScenarioDependenciesAttribute.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using System; | ||
using System.Linq; | ||
|
||
namespace SpecFlow.Autofac | ||
{ | ||
[AttributeUsage(AttributeTargets.Method)] | ||
public class ScenarioDependenciesAttribute : Attribute | ||
{ | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
Plugins/SpecFlow.Autofac.SpecFlowPlugin/SpecFlow.Autofac.SpecFlowPlugin.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<TargetFrameworks>$(SpecFlow_Runtime_TFM)</TargetFrameworks> | ||
<AssemblyOriginatorKeyFile>$(SpecFlow_KeyFile)</AssemblyOriginatorKeyFile> | ||
<SignAssembly>$(SpecFlow_EnableStrongNameSigning)</SignAssembly> | ||
<PublicSign>$(SpecFlow_PublicSign)</PublicSign> | ||
|
||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> | ||
<NuspecFile>$(MSBuildThisFileDirectory)SpecFlow.Autofac.nuspec</NuspecFile> | ||
|
||
<PublishRepositoryUrl>true</PublishRepositoryUrl> | ||
<EmbedUntrackedSources>true</EmbedUntrackedSources> | ||
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta-63127-02" PrivateAssets="All" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Autofac" Version="4.0.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\TechTalk.SpecFlow\TechTalk.SpecFlow.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
32 changes: 32 additions & 0 deletions
32
Plugins/SpecFlow.Autofac.SpecFlowPlugin/SpecFlow.Autofac.nuspec
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?xml version="1.0"?> | ||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> | ||
<metadata> | ||
<id>SpecFlow.Autofac</id> | ||
<version>$version$</version> | ||
<title>SpecFlow Autofac integration plugin</title> | ||
<authors>Gaspar Nagy, Spec Solutions, SpecFlow</authors> | ||
<owners>Gaspar Nagy, Spec Solutions, SpecFlow</owners> | ||
<description>SpecFlow plugin that enables to use Autofac for resolving test dependencies.</description> | ||
<summary>SpecFlow plugin that enables to use Autofac for resolving test dependencies.</summary> | ||
<language>en-US</language> | ||
<projectUrl>http://www.specflow.org</projectUrl> | ||
<iconUrl>http://go.specflow.org/specflow-nuget-icon</iconUrl> | ||
<copyright>Copyright © 2016-2019 Gaspar Nagy, Spec Solutions, SpecFlow</copyright> | ||
<requireLicenseAcceptance>false</requireLicenseAcceptance> | ||
<license type="file">LICENSE.txt</license> | ||
<tags>specflow autofac di dependency injection</tags> | ||
<dependencies> | ||
<dependency id="SpecFlow" version="[$version$]" /> | ||
<dependency id="Autofac" version="4.0.0" /> | ||
</dependencies> | ||
</metadata> | ||
|
||
<files> | ||
<file src="build\**\*" target="build" /> | ||
<file src="bin\$config$\net45\SpecFlow.Autofac.SpecFlowPlugin.*" target="lib\$SpecFlow_FullFramework_Runtime_TFM$" /> | ||
<file src="bin\$config$\netstandard2.0\SpecFlow.Autofac.SpecFlowPlugin.dll" target="lib\$SpecFlow_Core_Runtime_TFM$" /> | ||
<file src="bin\$config$\netstandard2.0\SpecFlow.Autofac.SpecFlowPlugin.pdb" target="lib\$SpecFlow_Core_Runtime_TFM$" /> | ||
|
||
<file src="$SolutionDir$LICENSE.txt" target="LICENSE.txt" /> | ||
</files> | ||
</package> |
11 changes: 11 additions & 0 deletions
11
Plugins/SpecFlow.Autofac.SpecFlowPlugin/build/SpecFlow.Autofac.props
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" TreatAsLocalProperty="TaskFolder;TaskAssembly"> | ||
|
||
<ItemGroup> | ||
<None Include="$(_SpecFlow_AutofacPluginPath)" > | ||
<Link>%(Filename)%(Extension)</Link> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
<Visible>False</Visible> | ||
</None> | ||
</ItemGroup> | ||
|
||
</Project> |
8 changes: 8 additions & 0 deletions
8
Plugins/SpecFlow.Autofac.SpecFlowPlugin/build/SpecFlow.Autofac.targets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<PropertyGroup> | ||
|
||
<_SpecFlow_AutofacPluginFramework Condition=" '$(TargetFrameworkIdentifier)' == '.NETCoreApp' ">netstandard2.0</_SpecFlow_AutofacPluginFramework> | ||
<_SpecFlow_AutofacPluginFramework Condition=" '$(TargetFrameworkIdentifier)' == '.NETFramework' ">net45</_SpecFlow_AutofacPluginFramework> | ||
<_SpecFlow_AutofacPluginPath>$(MSBuildThisFileDirectory)\..\lib\$(_SpecFlow_AutofacPluginFramework)\SpecFlow.Autofac.SpecFlowPlugin.dll</_SpecFlow_AutofacPluginPath> | ||
</PropertyGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters