Skip to content

Commit da170ca

Browse files
committed
Implement IServiceProviderIsService
1 parent be39309 commit da170ca

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

src/StructureMap.Microsoft.DependencyInjection/ContainerExtensions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ public static void Register(this IProfileRegistry registry, IEnumerable<ServiceD
137137
.LifecycleIs(Lifecycles.Container)
138138
.UseIfNone<StructureMapServiceScopeFactory>();
139139

140+
// Added in MEDI v6
141+
registry.For<IServiceProviderIsService>()
142+
.LifecycleIs(Lifecycles.Container)
143+
.UseIfNone<StructureMapServiceProviderIsService>();
144+
140145
foreach (var descriptor in descriptors)
141146
{
142147
registry.Register(descriptor);
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Microsoft.Extensions.DependencyInjection;
4+
5+
namespace StructureMap
6+
{
7+
public sealed class StructureMapServiceProviderIsService : IServiceProviderIsService
8+
{
9+
private readonly IContainer _container;
10+
11+
public StructureMapServiceProviderIsService(IContainer container) => _container = container;
12+
13+
// https://github.com/dotnet/dotnet/blob/d25d3482f4c3c509977cc4d959c80cb78b6ad9c8/src/runtime/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteFactory.cs#L778-L803
14+
public bool IsService(Type serviceType)
15+
{
16+
if (serviceType is null)
17+
{
18+
throw new ArgumentNullException(nameof(serviceType));
19+
}
20+
21+
// Querying for an open generic should return false (they aren't resolvable)
22+
if (serviceType.IsGenericTypeDefinition)
23+
{
24+
return false;
25+
}
26+
27+
if (_container.Model.HasDefaultImplementationFor(serviceType))
28+
{
29+
return true;
30+
}
31+
32+
33+
if (serviceType.IsConstructedGenericType && serviceType.GetGenericTypeDefinition() is Type genericDefinition)
34+
{
35+
// We special case IEnumerable since it isn't explicitly registered in the container
36+
// yet we can manifest instances of it when requested.
37+
return genericDefinition == typeof(IEnumerable<>) ||
38+
_container.Model.HasDefaultImplementationFor(genericDefinition);
39+
}
40+
41+
return false;
42+
}
43+
}
44+
}

test/StructureMap.Microsoft.DependencyInjection.Tests/StructureMapContainerTests.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ namespace StructureMap.Microsoft.DependencyInjection.Tests
1212
{
1313
public class StructureMapContainerTests : DependencyInjectionSpecificationTests
1414
{
15-
public override bool SupportsIServiceProviderIsService => false;
16-
1715
// The following tests don't pass with the SM adapter...
1816
private static readonly string[] SkippedTests =
1917
{
@@ -61,6 +59,14 @@ public void ConfigureAndRegisterDoNotPreventPopulate()
6159
Assert.NotNull(container.GetInstance<IFakeService>());
6260
Assert.NotNull(container.GetInstance<IFakeSingletonService>());
6361
Assert.NotNull(container.GetInstance<IFakeScopedService>());
62+
63+
var spis = container.GetInstance<IServiceProviderIsService>();
64+
Assert.True(spis.IsService(typeof(IFakeService)));
65+
Assert.True(spis.IsService(typeof(IFakeScopedService)));
66+
Assert.True(spis.IsService(typeof(IFakeSingletonService)));
67+
68+
Assert.False(spis.IsService(typeof(FakeService)));
69+
Assert.False(spis.IsService(typeof(IFakeServiceInstance)));
6470
}
6571

6672
[Fact]
@@ -77,6 +83,7 @@ public void ConfigureDoesNotRequirePopulate()
7783
Assert.NotNull(container.GetInstance<IFakeScopedService>());
7884

7985
Assert.NotNull(container.GetInstance<IServiceProvider>());
86+
Assert.NotNull(container.GetInstance<IServiceProviderIsService>());
8087
Assert.NotNull(container.GetInstance<IServiceScopeFactory>());
8188
}
8289

@@ -95,6 +102,7 @@ public void RegisterDoesNotRequirePopulate()
95102
Assert.NotNull(container.GetInstance<IFakeScopedService>());
96103

97104
Assert.NotNull(container.GetInstance<IServiceProvider>());
105+
Assert.NotNull(container.GetInstance<IServiceProviderIsService>());
98106
Assert.NotNull(container.GetInstance<IServiceScopeFactory>());
99107
}
100108

0 commit comments

Comments
 (0)