This repository has been archived by the owner on May 22, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enhance dependency injection scoping (#74)
Contributor: @shlomiassaf
- Loading branch information
1 parent
8128ae8
commit 1258fb0
Showing
5 changed files
with
211 additions
and
102 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
41 changes: 38 additions & 3 deletions
41
SpecFlow.DependencyInjection/DependencyInjectionTestObjectResolver.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 |
---|---|---|
@@ -1,15 +1,50 @@ | ||
using System; | ||
using System.Collections.Concurrent; | ||
using System.Reflection; | ||
using BoDi; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using TechTalk.SpecFlow.Infrastructure; | ||
|
||
namespace SolidToken.SpecFlow.DependencyInjection | ||
{ | ||
/* TODO | ||
If SpecFlow will add an "IObjectContainer.IsRegistered(Type type)" method next to the existing "IsRegistered<T>()" | ||
We can remove most of the code here! | ||
*/ | ||
public class DependencyInjectionTestObjectResolver : ITestObjectResolver | ||
{ | ||
public object ResolveBindingInstance(Type bindingType, IObjectContainer scenarioContainer) | ||
// Can remove if IsRegistered(Type type) exists | ||
private static readonly ConcurrentDictionary<Type, MethodInfo> IsRegisteredMethodInfoCache = | ||
new ConcurrentDictionary<Type, MethodInfo>(); | ||
|
||
// Can remove if IsRegistered(Type type) exists | ||
private static readonly MethodInfo IsRegisteredMethodInfo = typeof(DependencyInjectionTestObjectResolver) | ||
.GetMethod(nameof(IsRegistered), BindingFlags.Instance | BindingFlags.Public); | ||
|
||
// Can remove if IsRegistered(Type type) exists | ||
private static MethodInfo CreateGenericMethodInfo(Type t) => IsRegisteredMethodInfo.MakeGenericMethod(t); | ||
|
||
public object ResolveBindingInstance(Type bindingType, IObjectContainer container) | ||
{ | ||
// Can remove if IsRegistered(Type type) exists | ||
var mi = IsRegisteredMethodInfoCache.GetOrAdd(bindingType, CreateGenericMethodInfo); | ||
var registered = (bool) mi.Invoke(this, new object[] { container }); | ||
// var registered = container.IsRegistered(bindingType); | ||
|
||
return registered | ||
? container.Resolve(bindingType) | ||
: container.Resolve<IServiceProvider>().GetRequiredService(bindingType); | ||
} | ||
|
||
public bool IsRegistered<T>(IObjectContainer container) | ||
{ | ||
var provider = scenarioContainer.Resolve<IServiceProvider>(); | ||
return provider.GetService(bindingType); | ||
if (container.IsRegistered<T>()) | ||
return true; | ||
|
||
// IsRegistered is not recursive, it will only check the current container | ||
if (container is ObjectContainer c && c.BaseContainer != null) | ||
return IsRegistered<T>(c.BaseContainer); | ||
return false; | ||
} | ||
} | ||
} |
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
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
Oops, something went wrong.