diff --git a/src/StructureMap.Microsoft.DependencyInjection/ContainerExtensions.cs b/src/StructureMap.Microsoft.DependencyInjection/ContainerExtensions.cs index 0280146..dcad296 100644 --- a/src/StructureMap.Microsoft.DependencyInjection/ContainerExtensions.cs +++ b/src/StructureMap.Microsoft.DependencyInjection/ContainerExtensions.cs @@ -63,21 +63,19 @@ public static void Populate(this ConfigurationExpression config, IEnumerable - /// Populates the registry using the specified service descriptors. - /// - /// - /// This method should only be called once per container. - /// - /// The registry. - /// The service descriptors. + /// public static void Populate(this Registry registry, IEnumerable descriptors) { registry.Populate(descriptors, checkDuplicateCalls: false); } /// - /// Populates the registry using the specified service descriptors. + /// Populates the registry using the specified service descriptors, plus: + /// + /// + /// as per-container + /// as per-container + /// /// /// /// This method should only be called once per container. @@ -116,7 +114,26 @@ private static void ThrowIfMarkerInterfaceIsRegistered(PluginGraph graph) } } - private static void Register(this IProfileRegistry registry, IEnumerable descriptors) + /// + /// Configures with . + /// + /// + /// Unlike , this method may be be called more than once per container. + /// + /// The registry. + /// The service configurator. + public static void Configure(this IProfileRegistry registry, Func configure) => + registry.Register(configure(new SimpleServiceCollection())); + + /// + /// Registers the specified service descriptors. + /// + /// + /// Unlike , this method may be be called more than once per container. + /// + /// The registry. + /// The service descriptors. + public static void Register(this IProfileRegistry registry, IEnumerable descriptors) { foreach (var descriptor in descriptors) { @@ -155,5 +172,11 @@ private static Expression> 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, IServiceCollection + { + } } } diff --git a/src/StructureMap.Microsoft.DependencyInjection/ServiceCollectionExtensions.cs b/src/StructureMap.Microsoft.DependencyInjection/ServiceCollectionExtensions.cs index 0e956b0..ee13278 100644 --- a/src/StructureMap.Microsoft.DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/StructureMap.Microsoft.DependencyInjection/ServiceCollectionExtensions.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.DependencyInjection; +using System; +using Microsoft.Extensions.DependencyInjection; namespace StructureMap { @@ -13,5 +14,13 @@ public static IServiceCollection AddStructureMap(this IServiceCollection service { return services.AddSingleton>(new StructureMapServiceProviderFactory(registry)); } + + /// + /// Configures with . + /// + /// The service collection. + /// The service configurator. + /// The result of , which should be . + public static IServiceCollection Configure(this IServiceCollection services, Func configure) => configure(services); } } \ No newline at end of file diff --git a/test/StructureMap.Microsoft.DependencyInjection.Tests/StructureMapContainerTests.cs b/test/StructureMap.Microsoft.DependencyInjection.Tests/StructureMapContainerTests.cs index 8970654..e54464e 100644 --- a/test/StructureMap.Microsoft.DependencyInjection.Tests/StructureMapContainerTests.cs +++ b/test/StructureMap.Microsoft.DependencyInjection.Tests/StructureMapContainerTests.cs @@ -38,6 +38,29 @@ protected override IServiceProvider CreateServiceProvider(IServiceCollection ser return container.GetInstance(); } + [Fact] + public void ConfigureAndRegisterDoNotPreventPopulate() + { + var services = new ServiceCollection(); + services.AddTransient(); + + var container = new Container(); + container.Configure(config => + { + config.Register(services); + config.Register(services); + + config.Configure(ctx => ctx.AddScoped()); + config.Configure(ctx => ctx.AddSingleton()); + + config.Populate(services, checkDuplicateCalls: true); + }); + + Assert.NotNull(container.GetInstance()); + Assert.NotNull(container.GetInstance()); + Assert.NotNull(container.GetInstance()); + } + [Theory] [InlineData(true)] [InlineData(false)]