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);
            }
        }
Пример #4
0
        // 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);
            }
        }
Пример #7
0
        /// <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);
                }
            };
        }