private static void AddAutoCrossWiring( Container container, IServiceProvider provider, SimpleInjectorAddOptions builder) { var scopeFactory = provider.GetRequiredService <IServiceScopeFactory>(); var services = builder.Services; container.ResolveUnregisteredType += (s, e) => { if (e.Handled) { return; } Type serviceType = e.UnregisteredServiceType; ServiceDescriptor descriptor = FindServiceDescriptor(services, serviceType); if (descriptor != null) { Registration registration = CreateCrossWireRegistration( builder, provider, serviceType, ToLifestyle(descriptor.Lifetime)); e.Register(registration); } }; }
/// <summary> /// Sets up the basic configuration that allows Simple Injector to be used in frameworks that require /// the use of <see cref="IServiceCollection"/> for registration of framework components. /// In case of the absense of a /// <see cref="ContainerOptions.DefaultScopedLifestyle">DefaultScopedLifestyle</see>, this method /// will configure <see cref="AsyncScopedLifestyle"/> as the default scoped lifestyle. /// In case a <paramref name="setupAction"/> is supplied, that delegate will be called that allow /// further configuring the container. /// </summary> /// <param name="services">The framework's <see cref="IServiceCollection"/> instance.</param> /// <param name="container">The application's <see cref="Container"/> instance.</param> /// <param name="setupAction">An optional setup action.</param> /// <returns>The supplied <paramref name="services"/>.</returns> /// <exception cref="ArgumentNullException">Thrown when <paramref name="services"/> or /// <paramref name="container"/> are null references.</exception> public static IServiceCollection AddSimpleInjector( this IServiceCollection services, Container container, Action <SimpleInjectorAddOptions> setupAction = null) { if (services is null) { throw new ArgumentNullException(nameof(services)); } if (container is null) { throw new ArgumentNullException(nameof(container)); } var options = new SimpleInjectorAddOptions( services, container, new DefaultServiceProviderAccessor(container)); // This stores the options, which includes the IServiceCollection. IServiceCollection is required // when calling UseSimpleInjector to enable auto cross wiring. AddSimpleInjectorOptions(container, options); // Set lifestyle before calling setupAction. Code in the delegate might depend on that. TrySetDefaultScopedLifestyle(container); setupAction?.Invoke(options); return(services); }
/// <summary> /// Allows components that are built by Simple Injector to depend on the (non-generic) /// <see cref="ILogger">Microsoft.Extensions.Logging.ILogger</see> abstraction. Components are /// injected with an contextual implementation. Using this method, application components can simply /// depend on <b>ILogger</b> instead of its generic counter part, <b>ILogger<T></b>, which /// simplifies development. /// </summary> /// <param name="options">The options.</param> /// <returns>The supplied <paramref name="options"/>.</returns> /// <exception cref="ArgumentNullException"> /// Thrown when <paramref name="options"/> is a null reference.</exception> /// <exception cref="InvalidOperationException">Thrown when no <see cref="ILoggerFactory"/> entry /// can be found in the framework's list of services defined by <see cref="IServiceCollection"/>. /// </exception> public static SimpleInjectorAddOptions AddLogging(this SimpleInjectorAddOptions options) { if (options is null) { throw new ArgumentNullException(nameof(options)); } EnsureMethodOnlyCalledOnce(options, nameof(AddLogging), AddLoggingKey); // Both RootLogger and Logger<T> depend on ILoggerFactory VerifyLoggerFactoryAvailable(options.Services); // Cross-wire ILoggerFactory explicitly, because auto cross-wiring might be disabled by the user. options.Container.RegisterSingleton(() => options.GetRequiredFrameworkService <ILoggerFactory>()); Type genericLoggerType = GetGenericLoggerType(); options.Container.RegisterConditional( typeof(ILogger), c => c.Consumer is null ? typeof(RootLogger) : genericLoggerType.MakeGenericType(c.Consumer.ImplementationType), Lifestyle.Singleton, _ => true); return(options); }
/// <summary> /// Cross wires an ASP.NET Core or third-party service to the container, to allow the service to be /// injected into components that are built by Simple Injector. /// </summary> /// <param name="options">The options.</param> /// <param name="serviceType">The type of service object to ross-wire.</param> /// <returns>The supplied <paramref name="options"/>.</returns> /// <exception cref="ArgumentNullException">Thrown when one of the parameters is a null reference. /// </exception> public static SimpleInjectorAddOptions CrossWire( this SimpleInjectorAddOptions options, Type serviceType) { if (options is null) { throw new ArgumentNullException(nameof(options)); } if (serviceType is null) { throw new ArgumentNullException(nameof(serviceType)); } // At this point there is no IServiceProvider (ApplicationServices) yet, which is why we need to // postpone the registration of the cross-wired service. When the container gets locked, we will // (hopefully) have the IServiceProvider available. options.Container.Options.ContainerLocking += (s, e) => { Registration registration = CreateCrossWireRegistration( options, options.ApplicationServices, serviceType, DetermineLifestyle(serviceType, options.Services)); options.Container.AddRegistration(serviceType, registration); }; return(options); }
/// <summary> /// Allows components that are built by Simple Injector to depend on the (non-generic) /// <see cref="IStringLocalizer">Microsoft.Extensions.Localization.IStringLocalizer</see> abstraction. /// Components are injected with an contextual implementation. Using this method, application /// components can simply depend on <b>IStringLocalizer</b> instead of its generic counter part, /// <b>IStringLocalizer<T></b>, which simplifies development. /// </summary> /// <param name="options">The options.</param> /// <returns>The supplied <paramref name="options"/>.</returns> /// <exception cref="ArgumentNullException"> /// Thrown when <paramref name="options"/> is a null reference.</exception> /// <exception cref="InvalidOperationException">Thrown when no <see cref="IStringLocalizerFactory"/> /// entry can be found in the framework's list of services defined by <see cref="IServiceCollection"/>. /// </exception> /// <exception cref="ActivationException">Thrown when an <see cref="IStringLocalizer"/> is directly /// resolved from the container. Instead use <see cref="IStringLocalizer"/> within a constructor /// dependency.</exception> public static SimpleInjectorAddOptions AddLocalization(this SimpleInjectorAddOptions options) { if (options is null) { throw new ArgumentNullException(nameof(options)); } EnsureMethodOnlyCalledOnce(options, nameof(AddLocalization), AddLocalizationKey); VerifyStringLocalizerFactoryAvailable(options.Services); // Cross-wire IStringLocalizerFactory explicitly, because auto cross-wiring might be disabled. options.Container.RegisterSingleton( () => options.GetRequiredFrameworkService <IStringLocalizerFactory>()); Type genericLocalizerType = GetGenericLocalizerType(); options.Container.RegisterConditional( typeof(IStringLocalizer), c => c.Consumer is null ? throw new ActivationException( "IStringLocalizer is being resolved directly from the container, but this is not " + "supported as string localizers need to be related to a consuming type. Instead, " + "make IStringLocalizer a constructor dependency of the type it is used in.") : genericLocalizerType.MakeGenericType(c.Consumer.ImplementationType), Lifestyle.Singleton, _ => true); return(options); }
private static void AddAutoCrossWiring(SimpleInjectorAddOptions options) { // By using ContainerLocking, we ensure that this ResolveUnregisteredType registration is made // after all possible ResolveUnregisteredType registrations the users did themselves. options.Container.Options.ContainerLocking += (_, __) => { // If there's no IServiceProvider, the property will throw, which is something we want to do // at this point, not later on, when an unregistered type is resolved. IServiceProvider provider = options.ApplicationServices; options.Container.ResolveUnregisteredType += (_, e) => { if (!e.Handled) { Type serviceType = e.UnregisteredServiceType; ServiceDescriptor?descriptor = FindServiceDescriptor(options.Services, serviceType); if (descriptor != null) { Registration registration = CreateCrossWireRegistration( options, provider, serviceType, ToLifestyle(descriptor.Lifetime)); e.Register(registration); } } }; }; }
private static Registration CreateCrossWireRegistration( SimpleInjectorAddOptions options, IServiceProvider provider, Type serviceType, Lifestyle lifestyle) { var registration = lifestyle.CreateRegistration( serviceType, lifestyle == Lifestyle.Singleton ? BuildSingletonInstanceCreator(serviceType, provider) : BuildScopedInstanceCreator(serviceType, options.ServiceProviderAccessor), options.Container); // This registration is managed and disposed by IServiceProvider and should, therefore, not be // disposed (again) by Simple Injector. registration.SuppressDisposal = true; if (lifestyle == Lifestyle.Transient && typeof(IDisposable).IsAssignableFrom(serviceType)) { registration.SuppressDiagnosticWarning( DiagnosticType.DisposableTransientComponent, justification: "This is a cross-wired service. It will be disposed by IServiceScope."); } return(registration); }
/// <summary> /// Finalizes the configuration of Simple Injector on top of <see cref="IServiceCollection"/>. Will /// ensure framework components can be injected into Simple Injector-resolved components, unless /// <see cref="SimpleInjectorUseOptions.AutoCrossWireFrameworkComponents"/> is set to <c>false</c> /// using the <paramref name="setupAction"/>. /// </summary> /// <param name="provider">The application's <see cref="IServiceProvider"/>.</param> /// <param name="container">The application's <see cref="Container"/> instance.</param> /// <param name="setupAction">An optional setup action.</param> /// <returns>The supplied <paramref name="provider"/>.</returns> /// <exception cref="ArgumentNullException">Thrown when <paramref name="provider"/> or /// <paramref name="container"/> are null references.</exception> public static IServiceProvider UseSimpleInjector( this IServiceProvider provider, Container container, Action <SimpleInjectorUseOptions> setupAction = null) { if (provider is null) { throw new ArgumentNullException(nameof(provider)); } if (container is null) { throw new ArgumentNullException(nameof(container)); } SimpleInjectorAddOptions addOptions = GetOptions(container); RegisterServiceScope(provider, container); var useOptions = new SimpleInjectorUseOptions(addOptions, provider); setupAction?.Invoke(useOptions); if (useOptions.AutoCrossWireFrameworkComponents) { AddAutoCrossWiring(container, provider, addOptions); } return(provider); }
/// <summary> /// Finalizes the configuration of Simple Injector on top of <see cref="IServiceCollection"/>. Will /// ensure framework components can be injected into Simple Injector-resolved components, unless /// <see cref="SimpleInjectorUseOptions.AutoCrossWireFrameworkComponents"/> is set to <c>false</c> /// using the <paramref name="setupAction"/>. /// </summary> /// <param name="provider">The application's <see cref="IServiceProvider"/>.</param> /// <param name="container">The application's <see cref="Container"/> instance.</param> /// <param name="setupAction">An optional setup action.</param> /// <returns>The supplied <paramref name="provider"/>.</returns> /// <exception cref="ArgumentNullException">Thrown when <paramref name="provider"/> or /// <paramref name="container"/> are null references.</exception> //// I wanted to add this obsolete message in 4.8, but it was confusing considering the obsolete //// messages for everything on top of SimpleInjectorUseOptions. When those obsolete messages are //// resolved by the user, there is no harm in calling this method any longer. So it will get //// obsoleted in a later release. ////[Obsolete( //// "You are supplying a setup action, but due breaking changes in ASP.NET Core 3, the Simple " + //// "Injector container can get locked at an earlier stage, making it impossible to further setup " + //// "the container at this stage. Please call the UseSimpleInjector(IServiceProvider, Container) " + //// "overload instead. Take a look at the compiler warnings on the individual methods you are " + //// "calling inside your setupAction delegate to understand how to migrate them. " + //// " For more information, see: https://simpleinjector.org/aspnetcore. " + //// "Will be treated as an error from version 4.10. Will be removed in version 5.0.", //// error: false)] public static IServiceProvider UseSimpleInjector( this IServiceProvider provider, Container container, Action <SimpleInjectorUseOptions>?setupAction) { if (provider is null) { throw new ArgumentNullException(nameof(provider)); } if (container is null) { throw new ArgumentNullException(nameof(container)); } SimpleInjectorAddOptions addOptions = GetOptions(container); addOptions.SetServiceProviderIfNull(provider); var useOptions = new SimpleInjectorUseOptions(addOptions, provider); setupAction?.Invoke(useOptions); return(provider); }
/// <summary> /// Registers a service to be executed by the `TimedHostedService`. The TimedHostedService executes the service repeatedly in a specified interval. /// </summary> public static void AddTimedHostedService <TService>(this SimpleInjectorAddOptions options, Action <TimedHostedServiceSettings> configureTimedHostedService, Func <TService, CancellationToken, Task> executeTask) where TService : class { var settings = new TimedHostedServiceSettings(); configureTimedHostedService(settings); options.AddHostedService <TimedHostedService <TService> >(); options.Container.Register <TService>(); options.Container.RegisterInstance(new TimedHostedService <TService> .Settings(TimeSpan.FromSeconds(settings.Interval), settings.WatchdogUri, executeTask)); }
private static void EnsureMethodOnlyCalledOnce( SimpleInjectorAddOptions options, string methodName, object key) { if (options.Container.ContainerScope.GetItem(key) != null) { throw new InvalidOperationException( $"The {methodName} extension method can only be called once on a Container instance."); } else { options.Container.ContainerScope.SetItem(key, new object()); } }
private static void AddSimpleInjectorOptions(Container container, SimpleInjectorAddOptions builder) { var current = container.ContainerScope.GetItem(AddOptionsKey); if (current is null) { container.ContainerScope.SetItem(AddOptionsKey, builder); } else { throw new InvalidOperationException( $"The {nameof(AddSimpleInjector)} extension method can only be called once."); } }
private static void HookAspNetCoreHostHostedServiceServiceProviderInitialization( SimpleInjectorAddOptions options) { // ASP.NET Core 3's new Host class resolves hosted services much earlier in the pipeline. This // registration ensures that the IServiceProvider is assigned before such resolve takes place, // to ensure that that hosted service can be injected with cross-wired dependencies. options.Services.AddSingleton <IHostedService>(provider => { options.SetServiceProviderIfNull(provider); // We can't return null here, so we return an empty implementation. return(new NullSimpleInjectorHostedService()); }); }
/// <summary> /// Sets up the basic configuration that allows Simple Injector to be used in frameworks that require /// the use of <see cref="IServiceCollection"/> for registration of framework components. /// In case of the absense of a /// <see cref="ContainerOptions.DefaultScopedLifestyle">DefaultScopedLifestyle</see>, this method /// will configure <see cref="AsyncScopedLifestyle"/> as the default scoped lifestyle. /// In case a <paramref name="setupAction"/> is supplied, that delegate will be called that allow /// further configuring the container. /// </summary> /// <param name="services">The framework's <see cref="IServiceCollection"/> instance.</param> /// <param name="container">The application's <see cref="Container"/> instance.</param> /// <param name="setupAction">An optional setup action.</param> /// <returns>The supplied <paramref name="services"/>.</returns> /// <exception cref="ArgumentNullException">Thrown when <paramref name="services"/> or /// <paramref name="container"/> are null references.</exception> public static IServiceCollection AddSimpleInjector( this IServiceCollection services, Container container, Action <SimpleInjectorAddOptions>?setupAction = null) { if (services is null) { throw new ArgumentNullException(nameof(services)); } if (container is null) { throw new ArgumentNullException(nameof(container)); } var options = new SimpleInjectorAddOptions( services, container, new DefaultServiceProviderAccessor(container)); // Add the container; this simplifies registration of types that depend on the container, but need // to be constructed by MS.DI (such as generic activators). Those registrations don't need to add // the container themselves. services.TryAddSingleton(container); // This stores the options, which includes the IServiceCollection. IServiceCollection is required // when calling UseSimpleInjector to enable auto cross wiring. AddSimpleInjectorOptions(container, options); // Set lifestyle before calling setupAction. Code in the delegate might depend on that. TrySetDefaultScopedLifestyle(container); HookAspNetCoreHostHostedServiceServiceProviderInitialization(options); setupAction?.Invoke(options); RegisterServiceScope(options); if (options.AutoCrossWireFrameworkComponents) { AddAutoCrossWiring(options); } if (options.DisposeContainerWithServiceProvider) { AddContainerDisposalOnShutdown(services, options); } return(services); }
private static SimpleInjectorAddOptions GetOptions(Container container) { SimpleInjectorAddOptions options = (SimpleInjectorAddOptions)container.ContainerScope.GetItem(SimpleInjectorAddOptionsKey); if (options is null) { throw new InvalidOperationException( "Please ensure the " + $"{nameof(SimpleInjectorServiceCollectionExtensions.AddSimpleInjector)} extension " + "method is called on the IServiceCollection instance before using this method."); } return(options); }
/// <summary> /// Finalizes the configuration of Simple Injector on top of <see cref="IServiceCollection"/>. Will /// ensure framework components can be injected into Simple Injector-resolved components, unless /// <see cref="SimpleInjectorAddOptions.AutoCrossWireFrameworkComponents"/> is set to <c>false</c>. /// </summary> /// <param name="provider">The application's <see cref="IServiceProvider"/>.</param> /// <param name="container">The application's <see cref="Container"/> instance.</param> /// <returns>The supplied <paramref name="provider"/>.</returns> /// <exception cref="ArgumentNullException">Thrown when <paramref name="provider"/> or /// <paramref name="container"/> are null references.</exception> public static IServiceProvider UseSimpleInjector(this IServiceProvider provider, Container container) { if (provider is null) { throw new ArgumentNullException(nameof(provider)); } if (container is null) { throw new ArgumentNullException(nameof(container)); } SimpleInjectorAddOptions addOptions = GetOptions(container); addOptions.SetServiceProviderIfNull(provider); return(provider); }
/// <summary> /// Registers the given <typeparamref name="THostedService"/> in the Container as Singleton and /// adds it to the host's pipeline of hosted services. /// </summary> /// <typeparam name="THostedService">An <see cref="IHostedService"/> to register.</typeparam> /// <param name="options">The options.</param> /// <returns>The <paramref name="options"/>.</returns> public static SimpleInjectorAddOptions AddHostedService <THostedService>( this SimpleInjectorAddOptions options) where THostedService : class, IHostedService { if (options is null) { throw new ArgumentNullException(nameof(options)); } var registration = Lifestyle.Singleton.CreateRegistration <THostedService>(options.Container); // Let the built-in configuration system dispose this instance. registration.SuppressDisposal = true; options.Container.AddRegistration <THostedService>(registration); options.Services.AddSingleton <IHostedService>(_ => { try { return(options.Container.GetInstance <THostedService>()); } catch (ActivationException ex) when(ex.Message.Contains("is not registered")) { throw new ActivationException(ex.Message + " " + "ASP.NET Core is trying to resolve your " + $"{typeof(THostedService).ToFriendlyName()} hosted service that you registered by " + "calling the AddHostedService<THostedService>() extension method, but it can't be " + "resolved due to a missing registration. In ASP.NET Core 3 and up, hosted " + "services are resolved much earlier in the pipeline, before the 'Configure' " + "method of your Startup class is invoked. If you are registering the missing " + "service inside the 'Configure' method, that would be the likely cause of the " + "issue. To fix the problem, you should ensure that all registration to the " + "container are done during the 'ConfigureServices' method of the Startup class. " + "For more information, see: https://simpleinjector.org/generichost or " + "https://simpleinjector.org/aspnetcore.", ex); } }); return(options); }
// Note about implementation: We could have used the ASP.NET Core IApplicationLifetime or // IHostApplicationLifetime for this as well, but there are a few downsides to this: // * IApplicationLifetime is obsolete // * IHostApplicationLifetime is only available for ASP.NET Core >= 3.0 // * This requires ASP.NET Core, so this is less generic and couldn't be implemented in this library. // * It required much more research and testing to get right. private static void AddContainerDisposalOnShutdown( IServiceCollection services, SimpleInjectorAddOptions options) { services.TryAddSingleton(options.Container); // This wrapper implements disposable and allows the container to be disposed of when // IServiceProvider is disposed of. Just like Simple Injector, however, MS.DI will only // dispose of instances that are registered using this overload (not using AddSingleton<T>(T)). services.AddSingleton <ContainerDisposeWrapper>(); options.Container.Options.ContainerLocking += (_, __) => { // If there's no IServiceProvider, the property will throw, which is something we want to do // at this point, not later on, when an unregistered type is resolved. IServiceProvider provider = options.ApplicationServices; // In order for the wrapper to get disposed of, it needs to be resolved once. provider.GetRequiredService <ContainerDisposeWrapper>(); }; }
/// <summary> /// Registers the given <typeparamref name="THostedService"/> in the Container as Singleton and /// adds it to the host's pipeline of hosted services. /// </summary> /// <typeparam name="THostedService">An <see cref="IHostedService"/> to register.</typeparam> /// <param name="options">The options.</param> /// <returns>The <paramref name="options"/>.</returns> public static SimpleInjectorAddOptions AddHostedService <THostedService>( this SimpleInjectorAddOptions options) where THostedService : class, IHostedService { if (options is null) { throw new ArgumentNullException(nameof(options)); } var registration = Lifestyle.Singleton.CreateRegistration <THostedService>(options.Container); // Let the built-in configuration system dispose this instance. registration.SuppressDisposal = true; options.Container.AddRegistration <THostedService>(registration); options.Services.AddSingleton <IHostedService>( _ => options.Container.GetInstance <THostedService>()); return(options); }
/// <summary> /// Sets up the basic configuration that allows Simple Injector to be used in frameworks that require /// the use of <see cref="IServiceCollection"/> for registration of framework components. /// In case of the absense of a /// <see cref="ContainerOptions.DefaultScopedLifestyle">DefaultScopedLifestyle</see>, this method /// will configure <see cref="AsyncScopedLifestyle"/> as the default scoped lifestyle. /// In case a <paramref name="setupAction"/> is supplied, that delegate will be called that allow /// further configuring the container. /// </summary> /// <param name="services">The framework's <see cref="IServiceCollection"/> instance.</param> /// <param name="container">The application's <see cref="Container"/> instance.</param> /// <param name="setupAction">An optional setup action.</param> /// <returns>The supplied <paramref name="services"/>.</returns> /// <exception cref="ArgumentNullException">Thrown when <paramref name="services"/> or /// <paramref name="container"/> are null references.</exception> public static IServiceCollection AddSimpleInjector( this IServiceCollection services, Container container, Action <SimpleInjectorAddOptions>?setupAction = null) { if (services is null) { throw new ArgumentNullException(nameof(services)); } if (container is null) { throw new ArgumentNullException(nameof(container)); } var options = new SimpleInjectorAddOptions( services, container, new DefaultServiceProviderAccessor(container)); // This stores the options, which includes the IServiceCollection. IServiceCollection is required // when calling UseSimpleInjector to enable auto cross wiring. AddSimpleInjectorOptions(container, options); // Set lifestyle before calling setupAction. Code in the delegate might depend on that. TrySetDefaultScopedLifestyle(container); HookAspNetCoreHostHostedServiceServiceProviderInitialization(options); setupAction?.Invoke(options); RegisterServiceScope(options); if (options.AutoCrossWireFrameworkComponents) { AddAutoCrossWiring(options); } return(services); }
/// <summary> /// Adds basic Simple Injector integration for ASP.NET Core and returns a builder object that allow /// additional integration options to be applied. These basic integrations includes wrapping each web /// request in an <see cref="AsyncScopedLifestyle"/> scope and making the nessesary changes that make /// it possible for enabling the injection of framework components in Simple Injector-constructed /// components when <see cref="SimpleInjectorServiceCollectionExtensions.UseSimpleInjector"/> is called. /// </summary> /// <param name="options">The options to which the integration should be applied.</param> /// <returns>A new <see cref="SimpleInjectorAspNetCoreBuilder"/> instance that allows additional /// configurations to be made.</returns> /// <exception cref="ArgumentNullException">Thrown when <paramref name="options"/> is null.</exception> public static SimpleInjectorAspNetCoreBuilder AddAspNetCore(this SimpleInjectorAddOptions options) { if (options is null) { throw new ArgumentNullException(nameof(options)); } IServiceCollection services = options.Services; var container = options.Container; // Add the IHttpContextAccessor to allow Simple Injector cross wiring to work in ASP.NET Core. services.TryAddSingleton <IHttpContextAccessor, HttpContextAccessor>(); // Replace the default IServiceProviderAccessor with on that can use IHttpContextAccessor to // resolve instances that are scoped inside the current request. options.ServiceProviderAccessor = new AspNetCoreServiceProviderAccessor( new HttpContextAccessor(), options.ServiceProviderAccessor); services.UseSimpleInjectorAspNetRequestScoping(container); return(new SimpleInjectorAspNetCoreBuilder(options)); }
public void AddSimpleInjector(SimpleInjectorAddOptions options) { options.AddAspNetCore() .AddControllerActivation(); }
private static void RegisterServiceScope(SimpleInjectorAddOptions options) { options.Container.Register( () => options.ServiceScopeFactory.CreateScope(), Lifestyle.Scoped); }
internal SimpleInjectorUseOptions( SimpleInjectorAddOptions builder, IServiceProvider applicationServices) { this.Builder = builder; this.ApplicationServices = applicationServices; }
/// <summary> /// Cross wires an ASP.NET Core or third-party service to the container, to allow the service to be /// injected into components that are built by Simple Injector. /// </summary> /// <typeparam name="TService">The type of service object to cross-wire.</typeparam> /// <param name="options">The options.</param> /// <returns>The supplied <paramref name="options"/>.</returns> /// <exception cref="ArgumentNullException">Thrown when the parameter is a null reference. /// </exception> public static SimpleInjectorAddOptions CrossWire <TService>(this SimpleInjectorAddOptions options) where TService : class { return(CrossWire(options, typeof(TService))); }
internal SimpleInjectorAspNetCoreBuilder(SimpleInjectorAddOptions options) { this.options = options; }