Skip to content
Permalink
Fetching contributors…
Cannot retrieve contributors at this time
160 lines (139 sloc) 6.27 KB
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Microsoft.Extensions.DependencyInjection;
using StructureMap.Graph;
using StructureMap.Pipeline;
namespace StructureMap
{
public static class ContainerExtensions
{
/// <summary>
/// Populates the container using the specified service descriptors.
/// </summary>
/// <remarks>
/// This method should only be called once per container.
/// </remarks>
/// <param name="container">The container.</param>
/// <param name="descriptors">The service descriptors.</param>
public static void Populate(this IContainer container, IEnumerable<ServiceDescriptor> descriptors)
{
container.Populate(descriptors, checkDuplicateCalls: false);
}
/// <summary>
/// Populates the container using the specified service descriptors.
/// </summary>
/// <remarks>
/// This method should only be called once per container.
/// </remarks>
/// <param name="container">The container.</param>
/// <param name="descriptors">The service descriptors.</param>
/// <param name="checkDuplicateCalls">Specifies whether duplicate calls to Populate should throw.</param>
public static void Populate(this IContainer container, IEnumerable<ServiceDescriptor> descriptors, bool checkDuplicateCalls)
{
container.Configure(config => config.Populate(descriptors, checkDuplicateCalls));
}
/// <summary>
/// Populates the container using the specified service descriptors.
/// </summary>
/// <remarks>
/// This method should only be called once per container.
/// </remarks>
/// <param name="config">The configuration.</param>
/// <param name="descriptors">The service descriptors.</param>
public static void Populate(this ConfigurationExpression config, IEnumerable<ServiceDescriptor> descriptors)
{
config.Populate(descriptors, checkDuplicateCalls: false);
}
/// <summary>
/// Populates the container using the specified service descriptors.
/// </summary>
/// <remarks>
/// This method should only be called once per container.
/// </remarks>
/// <param name="config">The configuration.</param>
/// <param name="descriptors">The service descriptors.</param>
/// <param name="checkDuplicateCalls">Specifies whether duplicate calls to Populate should throw.</param>
public static void Populate(this ConfigurationExpression config, IEnumerable<ServiceDescriptor> descriptors, bool checkDuplicateCalls)
{
((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>
public static void Populate(this Registry registry, IEnumerable<ServiceDescriptor> descriptors)
{
registry.Populate(descriptors, checkDuplicateCalls: false);
}
/// <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>
/// <param name="checkDuplicateCalls">Specifies whether duplicate calls to Populate should throw.</param>
public static void Populate(this Registry registry, IEnumerable<ServiceDescriptor> descriptors, bool checkDuplicateCalls)
{
if (checkDuplicateCalls)
{
// HACK: We insert this action in order to prevent Populate being called twice on the same container.
registry.Configure(ThrowIfMarkerInterfaceIsRegistered);
}
registry.For<IMarkerInterface>();
registry.Policies.ConstructorSelector<AspNetConstructorSelector>();
registry.For<IServiceProvider>()
.LifecycleIs(Lifecycles.Container)
.Use<StructureMapServiceProvider>();
registry.For<IServiceScopeFactory>()
.LifecycleIs(Lifecycles.Container)
.Use<StructureMapServiceScopeFactory>();
registry.Register(descriptors);
}
private static void ThrowIfMarkerInterfaceIsRegistered(PluginGraph graph)
{
if (graph.HasFamily<IMarkerInterface>())
{
throw new InvalidOperationException("Populate should only be called once per container.");
}
}
private static void Register(this IProfileRegistry registry, IEnumerable<ServiceDescriptor> descriptors)
{
foreach (var descriptor in descriptors)
{
registry.Register(descriptor);
}
}
private static void Register(this IProfileRegistry registry, ServiceDescriptor descriptor)
{
if (descriptor.ImplementationType != null)
{
registry.For(descriptor.ServiceType)
.LifecycleIs(descriptor.Lifetime)
.Use(descriptor.ImplementationType);
return;
}
if (descriptor.ImplementationFactory != null)
{
registry.For(descriptor.ServiceType)
.LifecycleIs(descriptor.Lifetime)
.Use(descriptor.CreateFactory());
return;
}
registry.For(descriptor.ServiceType)
.LifecycleIs(descriptor.Lifetime)
.Use(descriptor.ImplementationInstance);
}
private static Expression<Func<IContext, object>> CreateFactory(this ServiceDescriptor descriptor)
{
return context => descriptor.ImplementationFactory(context.GetInstance<IServiceProvider>());
}
private interface IMarkerInterface { }
}
}
You can’t perform that action at this time.