Skip to content
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
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<VersionPrefix>2.2.0</VersionPrefix>
<VersionPrefix>3.0.0</VersionPrefix>
<Authors>dustinsoftware</Authors>
<TargetFramework>netstandard2.0</TargetFramework>
<NoWarn>$(NoWarn);CS1591</NoWarn>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ public static void Register(this IProfileRegistry registry, IEnumerable<ServiceD
.LifecycleIs(Lifecycles.Container)
.UseIfNone<StructureMapServiceScopeFactory>();

// Added in MEDI v6
registry.For<IServiceProviderIsService>()
.LifecycleIs(Lifecycles.Container)
.UseIfNone<StructureMapServiceProviderIsService>();

foreach (var descriptor in descriptors)
{
registry.Register(descriptor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@

<ItemGroup>
<PackageReference Include="StructureMap" Version="4.5.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;

namespace StructureMap
{
public sealed class StructureMapServiceProviderIsService : IServiceProviderIsService
{
private readonly IContainer _container;

public StructureMapServiceProviderIsService(IContainer container) => _container = container;

// https://github.com/dotnet/dotnet/blob/d25d3482f4c3c509977cc4d959c80cb78b6ad9c8/src/runtime/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/CallSiteFactory.cs#L778-L803
public bool IsService(Type serviceType)
{
if (serviceType is null)
{
throw new ArgumentNullException(nameof(serviceType));
}

// Querying for an open generic should return false (they aren't resolvable)
if (serviceType.IsGenericTypeDefinition)
{
return false;
}

if (_container.Model.HasDefaultImplementationFor(serviceType))
{
return true;
}

if (serviceType.IsConstructedGenericType && serviceType.GetGenericTypeDefinition() is Type genericDefinition)
{
// We special case IEnumerable since it isn't explicitly registered in the container
// yet we can manifest instances of it when requested.
return genericDefinition == typeof(IEnumerable<>);
}

return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Specification.Tests" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Specification.Tests" Version="6.0.0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public void ConfigureAndRegisterDoNotPreventPopulate()
{
var services = new ServiceCollection();
services.AddTransient<IFakeService, FakeService>();
services.AddSingleton<IComparer<string>>(StringComparer.OrdinalIgnoreCase);

var container = new Container();
container.Configure(config =>
Expand All @@ -59,6 +60,33 @@ public void ConfigureAndRegisterDoNotPreventPopulate()
Assert.NotNull(container.GetInstance<IFakeService>());
Assert.NotNull(container.GetInstance<IFakeSingletonService>());
Assert.NotNull(container.GetInstance<IFakeScopedService>());

var spis = container.GetInstance<IServiceProviderIsService>();
Assert.True(spis.IsService(typeof(IFakeService)));
Assert.True(spis.IsService(typeof(IFakeScopedService)));
Assert.True(spis.IsService(typeof(IFakeSingletonService)));

Assert.False(spis.IsService(typeof(FakeService)));
Assert.False(spis.IsService(typeof(IFakeServiceInstance)));

// Open generics never resolve
Assert.False(spis.IsService(typeof(IComparer<>)));
Assert.False(spis.IsService(typeof(IEnumerable<>)));

// Registered closed generic does resolve
Assert.True(spis.IsService(typeof(IComparer<string>)));

// Unregistered closed generic does not resolve
Assert.False(spis.IsService(typeof(IComparer<IFakeService>)));

// IEnumerable<> of registered types does resolve
Assert.True(spis.IsService(typeof(IEnumerable<IFakeService>)));
Assert.True(spis.IsService(typeof(IEnumerable<IFakeScopedService>)));
Assert.True(spis.IsService(typeof(IEnumerable<IFakeSingletonService>)));

// IEnumerable<> of unregistered types also resolves
Assert.True(spis.IsService(typeof(IEnumerable<FakeService>)));
Assert.True(spis.IsService(typeof(IEnumerable<IFakeServiceInstance>)));
}

[Fact]
Expand All @@ -75,6 +103,7 @@ public void ConfigureDoesNotRequirePopulate()
Assert.NotNull(container.GetInstance<IFakeScopedService>());

Assert.NotNull(container.GetInstance<IServiceProvider>());
Assert.NotNull(container.GetInstance<IServiceProviderIsService>());
Assert.NotNull(container.GetInstance<IServiceScopeFactory>());
}

Expand All @@ -93,6 +122,7 @@ public void RegisterDoesNotRequirePopulate()
Assert.NotNull(container.GetInstance<IFakeScopedService>());

Assert.NotNull(container.GetInstance<IServiceProvider>());
Assert.NotNull(container.GetInstance<IServiceProviderIsService>());
Assert.NotNull(container.GetInstance<IServiceScopeFactory>());
}

Expand Down