private static void CrossWireServiceScope(Container container, IApplicationBuilder builder) { if (container.Options.DefaultScopedLifestyle == null) { throw new InvalidOperationException( "To be able to cross-wire a service with a transient or scoped lifestyle, " + "please ensure that the container is configured with a default scoped lifestyle by " + "setting the Container.Options.DefaultScopedLifestyle property with the required " + "scoped lifestyle for your type of application. In ASP.NET Core, the typical " + $"lifestyle to use is the {nameof(AsyncScopedLifestyle)}. " + "See: https://simpleinjector.org/lifestyles#scoped"); } if (container.GetItem(ServiceScopeKey) == null) { var scopeFactory = builder.ApplicationServices.GetRequiredService <IServiceScopeFactory>(); // We use unregistered type resolution, to allow the user to register IServiceScope manually // if he needs. container.ResolveUnregisteredType += (s, e) => { if (e.UnregisteredServiceType == typeof(IServiceScope) && !e.Handled) { e.Register(Lifestyle.Scoped.CreateRegistration(scopeFactory.CreateScope, container)); } }; container.SetItem(ServiceScopeKey, new object()); } }
/// <summary> /// Allows registrations made using the <see cref="IServiceCollection"/> API to be resolved by Simple Injector. /// </summary> /// <param name="container">The container.</param> /// <param name="app">The <see cref="IApplicationBuilder"/> instance.</param> public static void AutoCrossWireAspNetComponents(this Container container, IApplicationBuilder app) { if (container == null) { throw new ArgumentNullException(nameof(container)); } if (app == null) { throw new ArgumentNullException(nameof(app)); } var services = (IServiceCollection)container.GetItem(CrossWireContextKey); if (services == null) { throw new InvalidOperationException( "To use this method, please make sure cross-wiring is enabled, by invoking " + $"the {nameof(EnableSimpleInjectorCrossWiring)} extension method as part of the " + "ConfigureServices method of the Startup class. " + "See https://simpleinjector.org/aspnetcore for more information."); } if (container.Options.DefaultScopedLifestyle == null) { throw new InvalidOperationException( "To be able to allow auto cross-wiring, please ensure that the container is configured with a " + "default scoped lifestyle by setting the Container.Options.DefaultScopedLifestyle property " + "with the required scoped lifestyle for your type of application. In ASP.NET Core, the typical " + $"lifestyle to use is the {nameof(AsyncScopedLifestyle)}. " + "See: https://simpleinjector.org/lifestyles#scoped"); } CrossWireServiceScope(container, app); container.ResolveUnregisteredType += (s, e) => { if (e.Handled) { return; } Type serviceType = e.UnregisteredServiceType; ServiceDescriptor descriptor = FindServiceDescriptor(services, serviceType); if (descriptor != null) { Lifestyle lifestyle = ToLifestyle(descriptor.Lifetime); Registration registration = lifestyle == Lifestyle.Singleton ? CreateSingletonRegistration(container, serviceType, app) : CreateNonSingletonRegistration(container, serviceType, app, lifestyle); e.Register(registration); } }; }
/// <summary> /// Enables ASP.NET Core services to be cross-wired in the Container. This method should be called /// in the <b>ConfigureServices</b> method of the application's <b>Startup</b> class. When cross-wiring /// is enabled, individual cross-wire registrations can be made by calling /// <see cref="CrossWire{TService}(Container, IApplicationBuilder)"/>. /// </summary> /// <param name="services">The ASP.NET application builder instance that references all /// framework components.</param> /// <param name="container">The container.</param> public static void EnableSimpleInjectorCrossWiring(this IServiceCollection services, Container container) { Requires.IsNotNull(services, nameof(services)); Requires.IsNotNull(container, nameof(container)); if (container.GetItem(CrossWireContextKey) == null) { container.SetItem(CrossWireContextKey, services); } }
// This method will never return null. internal static LifetimeScopeManager GetLifetimeScopeManager(this Container container) { var manager = (LifetimeScopeManager)container.GetItem(ManagerKey); if (manager == null) { lock (ManagerKey) { manager = (LifetimeScopeManager)container.GetItem(ManagerKey); if (manager == null) { manager = new LifetimeScopeManager(); container.SetItem(ManagerKey, manager); } } } return(manager); }
private static IServiceCollection GetServiceCollection(Container container) { var context = (IServiceCollection)container.GetItem(CrossWireContextKey); if (context == null) { throw new InvalidOperationException( "Cross-wiring has to be enabled first. Please make sure the " + $"{nameof(EnableSimpleInjectorCrossWiring)} extension method is called first by " + "adding it to the ConfigureServices method as follows: " + Environment.NewLine + $"services.{nameof(EnableSimpleInjectorCrossWiring)}(container);" + Environment.NewLine + "See: https://simpleinjector.org/aspnetcore"); } return(context); }
/// <summary> /// Enables ASP.NET Core services to be cross-wired in the Container. This method should be called /// in the <b>ConfigureServices</b> method of the application's <b>Startup</b> class. When cross-wiring /// is enabled, individual cross-wire registrations can be made by calling /// <see cref="CrossWire{TService}(Container, IApplicationBuilder)"/>. /// </summary> /// <param name="services">The ASP.NET application builder instance that references all /// framework components.</param> /// <param name="container">The container.</param> public static void EnableSimpleInjectorCrossWiring(this IServiceCollection services, Container container) { if (container == null) { throw new ArgumentNullException(nameof(container)); } if (services == null) { throw new ArgumentNullException(nameof(services)); } if (container.GetItem(CrossWireContextKey) == null) { container.SetItem(CrossWireContextKey, services); } }
/// <summary> /// Allows registrations made using the <see cref="IServiceCollection"/> API to be resolved by Simple Injector. /// </summary> /// <param name="container">The container.</param> /// <param name="app">The <see cref="IApplicationBuilder"/> instance.</param> public static void AutoCrossWireAspNetComponents(this Container container, IApplicationBuilder app) { if (container == null) { throw new ArgumentNullException(nameof(container)); } if (app == null) { throw new ArgumentNullException(nameof(app)); } var services = (IServiceCollection)container.GetItem(CrossWireContextKey); if (services == null) { throw new InvalidOperationException( "To use this method, please make sure cross-wiring is enabled, by invoking " + $"the {nameof(EnableSimpleInjectorCrossWiring)} extension method as part of the " + "ConfigureServices method of the Startup class. " + "See https://simpleinjector.org/aspnetcore for more information."); } if (container.Options.DefaultScopedLifestyle == null) { throw new InvalidOperationException( "To be able to allow auto cross-wiring, please ensure that the container is configured with a " + "default scoped lifestyle by setting the Container.Options.DefaultScopedLifestyle property " + "with the required scoped lifestyle for your type of application. In ASP.NET Core, the typical " + $"lifestyle to use is the {nameof(AsyncScopedLifestyle)}. " + "See: https://simpleinjector.org/lifestyles#scoped"); } CrossWireServiceScope(container, app); IHttpContextAccessor accessor = GetHttpContextAccessor(app); container.ResolveUnregisteredType += (s, e) => { if (e.Handled) { return; } Type serviceType = e.UnregisteredServiceType; ServiceDescriptor descriptor = FindServiceDescriptor(services, serviceType); if (descriptor != null) { Lifestyle lifestyle = ToLifestyle(descriptor.Lifetime); // Create a cross-wire registration that calls back into the .NET Core container. Registration registration = lifestyle.CreateRegistration(serviceType, () => GetServiceProvider(accessor, container).GetRequiredService(serviceType), container); // Apply the required suppressions. if (lifestyle == Lifestyle.Transient && typeof(IDisposable).IsAssignableFrom(serviceType)) { registration.SuppressDiagnosticWarning( DiagnosticType.DisposableTransientComponent, justification: "This is a cross-wired service. ASP.NET will ensure it gets disposed."); } e.Register(registration); } }; }