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
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,19 @@ public static void Populate(this ConfigurationExpression config, IEnumerable<Ser
((Registry) config).Populate(descriptors, checkDuplicateCalls);
}

/// <summary>
/// Populates the registry using the specified service descriptors.
/// </summary>
/// <remarks>
/// This method should only be called once per container.
/// </remarks>
/// <param name="registry">The registry.</param>
/// <param name="descriptors">The service descriptors.</param>
/// <inheritdoc cref="Populate(Registry, IEnumerable{ServiceDescriptor}, bool)"/>
public static void Populate(this Registry registry, IEnumerable<ServiceDescriptor> descriptors)
{
registry.Populate(descriptors, checkDuplicateCalls: false);
}

/// <summary>
/// Populates the registry using the specified service descriptors.
/// Populates the registry using the specified service descriptors, plus:
/// <list type="bullet">
/// <item><see cref="AspNetConstructorSelector"/></item>
/// <item><see cref="StructureMapServiceProvider"/> as per-container <see cref="IServiceProvider"/></item>
/// <item><see cref="StructureMapServiceScopeFactory"/> as per-container <see cref="IServiceScopeFactory"/></item>
/// </list>
/// </summary>
/// <remarks>
/// This method should only be called once per container.
Expand Down Expand Up @@ -116,7 +114,26 @@ private static void ThrowIfMarkerInterfaceIsRegistered(PluginGraph graph)
}
}

private static void Register(this IProfileRegistry registry, IEnumerable<ServiceDescriptor> descriptors)
/// <summary>
/// Configures <paramref name="registry"/> with <paramref name="configure"/>.
/// </summary>
/// <remarks>
/// Unlike <see cref="Populate(Registry, IEnumerable{ServiceDescriptor})"/>, this method may be be called more than once per container.
/// </remarks>
/// <param name="registry">The registry.</param>
/// <param name="configure">The service configurator.</param>
public static void Configure(this IProfileRegistry registry, Func<IServiceCollection, IServiceCollection> configure) =>
registry.Register(configure(new SimpleServiceCollection()));

/// <summary>
/// Registers the specified service descriptors.
/// </summary>
/// <remarks>
/// Unlike <see cref="Populate(Registry, IEnumerable{ServiceDescriptor})"/>, this method may be be called more than once per container.
/// </remarks>
/// <param name="registry">The registry.</param>
/// <param name="descriptors">The service descriptors.</param>
public static void Register(this IProfileRegistry registry, IEnumerable<ServiceDescriptor> descriptors)
{
foreach (var descriptor in descriptors)
{
Expand Down Expand Up @@ -155,5 +172,11 @@ private static Expression<Func<IContext, object>> CreateFactory(this ServiceDesc
}

private interface IMarkerInterface { }

// We don't depend on the package that declares ServiceCollection,
// but even if we did this is slightly better because we don't need its IsReadOnly checks
private class SimpleServiceCollection : List<ServiceDescriptor>, IServiceCollection
{
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using Microsoft.Extensions.DependencyInjection;

namespace StructureMap
{
Expand All @@ -13,5 +14,13 @@ public static IServiceCollection AddStructureMap(this IServiceCollection service
{
return services.AddSingleton<IServiceProviderFactory<Registry>>(new StructureMapServiceProviderFactory(registry));
}

/// <summary>
/// Configures <paramref name="services"/> with <paramref name="configure"/>.
/// </summary>
/// <param name="services">The service collection.</param>
/// <param name="configure">The service configurator.</param>
/// <returns>The result of <paramref name="configure"/>, which should be <paramref name="services"/>.</returns>
public static IServiceCollection Configure(this IServiceCollection services, Func<IServiceCollection, IServiceCollection> configure) => configure(services);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,29 @@ protected override IServiceProvider CreateServiceProvider(IServiceCollection ser
return container.GetInstance<IServiceProvider>();
}

[Fact]
public void ConfigureAndRegisterDoNotPreventPopulate()
{
var services = new ServiceCollection();
services.AddTransient<IFakeService, FakeService>();

var container = new Container();
container.Configure(config =>
{
config.Register(services);
config.Register(services);

config.Configure(ctx => ctx.AddScoped<IFakeScopedService, FakeService>());
config.Configure(ctx => ctx.AddSingleton<IFakeSingletonService, FakeService>());

config.Populate(services, checkDuplicateCalls: true);
});

Assert.NotNull(container.GetInstance<IFakeService>());
Assert.NotNull(container.GetInstance<IFakeSingletonService>());
Assert.NotNull(container.GetInstance<IFakeScopedService>());
}

[Theory]
[InlineData(true)]
[InlineData(false)]
Expand Down
Loading