Esempio n. 1
0
        private void RegisterInterfaces(Type component, SimpleInjector.Lifestyle lifestyle)
        {
            var registration = lifestyle.CreateRegistration(component, _container);

            var interfaces = component.GetInterfaces();

            foreach (var serviceType in interfaces)
            {
                addRegistration(serviceType, registration);
            }
        }
Esempio n. 2
0
        public SimpleInjectorJobActivator(Injector.Container container, Injector.Lifestyle lifestyle)
        {
            if (container == null)
            {
                throw new ArgumentNullException("container");
            }

            if (lifestyle == null)
            {
                throw new ArgumentNullException("lifestyle");
            }

            _container = container;
            _lifestyle = lifestyle;
        }
Esempio n. 3
0
        public static void Configure(Container container, SimpleInjector.Lifestyle lifeStyle)
        {
            container.Register<IFileParserService, FileParserService>(lifeStyle);
            container.Register<IGridService, GridService>(lifeStyle);
            container.Register<IPositionService, PositionService>(lifeStyle);
            container.Register<IGameService, GameService>(lifeStyle);
            container.Register<IMoveFactory, MoveFactory>(lifeStyle);
            container.Register<ITurtleService, TurtleService>(lifeStyle);
            container.Collection.Register(typeof(IMoveService), new[]
            {
                typeof(MoveForwardService),
                typeof(MoveLeftService),
                typeof(MoveRightService)
            });

        }
Esempio n. 4
0
        /// <summary>
        /// Ensures that the decorator type that is returned from <paramref name="decoratorTypeFactory"/> is
        /// supplied when the supplied <paramref name="predicate"/> returns <b>true</b> and cached with the given
        /// <paramref name="lifestyle"/>, wrapping the original registered <paramref name="serviceType"/>, by
        /// injecting that service type into the constructor of the decorator type that is returned by the
        /// supplied <paramref name="decoratorTypeFactory"/>.
        /// Multiple decorators may be applied to the same <paramref name="serviceType"/>. Decorators can be
        /// applied to both open, closed, and non-generic service types.
        /// </summary>
        /// <remarks>
        /// <para>
        /// The types returned from the <paramref name="decoratorTypeFactory"/> may be non-generic,
        /// closed-generic, open-generic and even partially-closed generic. The container will try to fill in
        /// the generic parameters based on the resolved service type.
        /// </para>
        /// <para>
        /// The <b>RegisterDecorator</b> method works by hooking onto the container's
        /// <see cref="Container.ExpressionBuilt">ExpressionBuilt</see> event. This event fires after the
        /// <see cref="Container.ResolveUnregisteredType">ResolveUnregisteredType</see> event, which allows
        /// decoration of types that are resolved using unregistered type resolution.
        /// </para>
        /// <para>
        /// Multiple decorators can be applied to the same service type. The order in which they are registered
        /// is the order they get applied in. This means that the decorator that gets registered first, gets
        /// applied first, which means that the next registered decorator, will wrap the first decorator, which
        /// wraps the original service type.
        /// </para>
        /// <para>
        /// Constructor injection will be used on that type, and although it may have many constructor
        /// arguments, it must have exactly one argument of the type of <paramref name="serviceType"/>, or an
        /// argument of type <see cref="Func{TResult}"/> where <b>TResult</b> is <paramref name="serviceType"/>.
        /// An exception will be thrown when this is not the case.
        /// </para>
        /// <para>
        /// The type returned from <paramref name="decoratorTypeFactory"/> may have a constructor with an
        /// argument of type <see cref="Func{T}"/> where <b>T</b> is <paramref name="serviceType"/>. In this
        /// case, the library will not inject the decorated <paramref name="serviceType"/> itself into the
        /// decorator instance, but it will inject a <see cref="Func{T}"/> that allows
        /// creating instances of the decorated type, according to the lifestyle of that type. This enables
        /// more advanced scenarios, such as executing the decorated types on a different thread, or executing
        /// decorated instance within a certain scope (such as a lifetime scope).
        /// </para>
        /// </remarks>
        /// <example>
        /// The following is an example of the registration of a decorator through the factory delegate:
        /// <code lang="cs"><![CDATA[
        /// container.Register<ICommandHandler<MoveCustomerCommand>, MoveCustomerCommandHandler>();
        ///
        /// container.RegisterDecorator(
        ///     typeof(ICommandHandler<>),
        ///     context => typeof(LoggingCommandHandler<,>).MakeGenericType(
        ///         typeof(LoggingCommandHandler<,>).GetGenericArguments().First(),
        ///         context.ImplementationType),
        ///     Lifestyle.Transient,
        ///     context => true);
        ///
        /// var handler = container.GetInstance<ICommandHandler<MoveCustomerCommand>>();
        ///
        /// Assert.IsInstanceOfType(handler,
        ///     typeof(LoggingCommandHandler<MoveCustomerCommand, MoveCustomerCommandHandler>));
        ///
        /// ]]></code>
        /// The code above allows a generic <b>LoggingCommandHandler&lt;TCommand, TImplementation&gt;</b> to
        /// be applied to command handlers, where the second generic argument will be filled in using the
        /// contextual information.
        /// </example>
        /// <param name="serviceType">The definition of the (possibly open generic) service type that will
        /// be wrapped by the decorator type that is returned from <paramref name="decoratorTypeFactory"/>.</param>
        /// <param name="decoratorTypeFactory">A factory that allows building Type objects that define the
        /// decorators to inject, based on the given contextual information. The delegate is allowed to return
        /// (partially) open-generic types.</param>
        /// <param name="lifestyle">The lifestyle that specifies how the returned decorator will be cached.</param>
        /// <param name="predicate">The predicate that determines whether the decorator must be applied to a
        /// service type.</param>
        /// <exception cref="ArgumentNullException">Thrown when one of the arguments is a null reference.</exception>
        public void RegisterDecorator(Type serviceType,
                                      Func <DecoratorPredicateContext, Type> decoratorTypeFactory, Lifestyle lifestyle,
                                      Predicate <DecoratorPredicateContext> predicate)
        {
            Requires.IsNotNull(serviceType, nameof(serviceType));
            Requires.IsNotNull(decoratorTypeFactory, nameof(decoratorTypeFactory));
            Requires.IsNotNull(lifestyle, nameof(lifestyle));
            Requires.IsNotNull(predicate, nameof(predicate));

            var interceptor = new DecoratorInterceptor(
                new DecoratorExpressionInterceptorData(
                    this, serviceType, null, predicate, lifestyle, decoratorTypeFactory));

            this.ExpressionBuilt += interceptor.ExpressionBuilt;
        }
Esempio n. 5
0
 /// <summary>
 /// Ensures that the supplied <paramref name="decoratorType"/> decorator is returned and cached with
 /// the given <paramref name="lifestyle"/>, wrapping the original registered
 /// <paramref name="serviceType"/>, by injecting that service type into the constructor of the
 /// supplied <paramref name="decoratorType"/>. Multiple decorators may be applied to the same
 /// <paramref name="serviceType"/>. Decorators can be applied to both open, closed, and non-generic
 /// service types.
 /// </summary>
 /// <remarks>
 /// <para>
 /// The <b>RegisterDecorator</b> method works by hooking onto the container's
 /// <see cref="Container.ExpressionBuilt">ExpressionBuilt</see> event. This event fires after the
 /// <see cref="Container.ResolveUnregisteredType">ResolveUnregisteredType</see> event, which allows
 /// decoration of types that are resolved using unregistered type resolution.
 /// </para>
 /// <para>
 /// Multiple decorators can be applied to the same service type. The order in which they are registered
 /// is the order they get registered. This means that the decorator that gets registered first, gets
 /// applied first, which means that the next registered decorator, will wrap the first decorator, which
 /// wraps the original service type.
 /// </para>
 /// <para>
 /// Constructor injection will be used on that type, and although it may have many constructor
 /// arguments, it must have exactly one argument of the type of <paramref name="serviceType"/>, or an
 /// argument of type <see cref="Func{TResult}"/> where <b>TResult</b> is <paramref name="serviceType"/>.
 /// An exception will be thrown when this is not the case.
 /// </para>
 /// <para>
 /// The registered <paramref name="decoratorType"/> may have a constructor with an argument of type
 /// <see cref="Func{T}"/> where <b>T</b> is <paramref name="serviceType"/>. In this case, the
 /// will not inject the decorated <paramref name="serviceType"/> itself into the
 /// <paramref name="decoratorType"/> instance, but it will inject a <see cref="Func{T}"/> that allows
 /// creating instances of the decorated type, according to the lifestyle of that type. This enables
 /// more advanced scenarios, such as executing the decorated types on a different thread, or executing
 /// decorated instance within a certain scope (such as a lifetime scope).
 /// </para>
 /// </remarks>
 /// <example>
 /// Please see the <see cref="RegisterDecorator(Type, Type)">RegisterDecorator</see> method
 /// for more information.
 /// </example>
 /// <param name="serviceType">The definition of the (possibly open generic) service type that will
 /// be wrapped by the given <paramref name="decoratorType"/>.</param>
 /// <param name="decoratorType">The definition of the (possibly open generic) decorator type that will
 /// be used to wrap the original service type.</param>
 /// <param name="lifestyle">The lifestyle that specifies how the returned decorator will be cached.</param>
 /// <exception cref="ArgumentNullException">Thrown when one of the arguments is a null reference.</exception>
 /// <exception cref="ArgumentException">Thrown when <paramref name="serviceType"/> is not
 /// an open generic type, when <paramref name="decoratorType"/> does not inherit from or
 /// implement <paramref name="serviceType"/>, when <paramref name="decoratorType"/>
 /// does not have a single public constructor, or when <paramref name="decoratorType"/> does
 /// not contain a constructor that has exactly one argument of type
 /// <paramref name="serviceType"/> or <see cref="Func{T}"/> where <b>T</b> is
 /// <paramref name="serviceType"/>.</exception>
 public void RegisterDecorator(Type serviceType, Type decoratorType, Lifestyle lifestyle)
 {
     this.RegisterDecoratorCore(serviceType, decoratorType, lifestyle: lifestyle);
 }
Esempio n. 6
0
 /// <summary>
 /// Ensures that the supplied <typeparamref name="TDecorator"/> decorator is returned and cached with
 /// the given <paramref name="lifestyle"/>, wrapping the original registered
 /// <typeparamref name="TService"/>, by injecting that service type into the constructor of the
 /// supplied <typeparamref name="TDecorator"/>. Multiple decorators may be applied to the same
 /// <typeparamref name="TService"/>. Decorators can be applied to both open, closed, and non-generic
 /// service types.
 /// </summary>
 /// <remarks>
 /// <para>
 /// The <b>RegisterDecorator</b> method works by hooking onto the container's
 /// <see cref="Container.ExpressionBuilt">ExpressionBuilt</see> event. This event fires after the
 /// <see cref="Container.ResolveUnregisteredType">ResolveUnregisteredType</see> event, which allows
 /// decoration of types that are resolved using unregistered type resolution.
 /// </para>
 /// <para>
 /// Multiple decorators can be applied to the same service type. The order in which they are registered
 /// is the order they get registered. This means that the decorator that gets registered first, gets
 /// applied first, which means that the next registered decorator, will wrap the first decorator, which
 /// wraps the original service type.
 /// </para>
 /// <para>
 /// Constructor injection will be used on that type, and although it may have many constructor
 /// arguments, it must have exactly one argument of the type of <typeparamref name="TService"/>, or an
 /// argument of type <see cref="Func{TResult}"/> where <b>TResult</b> is <typeparamref name="TService"/>.
 /// An exception will be thrown when this is not the case.
 /// </para>
 /// <para>
 /// The registered <typeparamref name="TDecorator"/> may have a constructor with an argument of type
 /// <see cref="Func{T}"/> where <b>T</b> is <typeparamref name="TService"/>. In this case, the
 /// will not inject the decorated <typeparamref name="TService"/> itself into the
 /// <typeparamref name="TDecorator"/> instance, but it will inject a <see cref="Func{T}"/> that allows
 /// creating instances of the decorated type, according to the lifestyle of that type. This enables
 /// more advanced scenarios, such as executing the decorated types on a different thread, or executing
 /// decorated instance within a certain scope (such as a lifetime scope).
 /// </para>
 /// </remarks>
 /// <example>
 /// Please see <see cref="RegisterDecorator(Type, Type)"/> for an example.
 /// </example>
 /// <typeparam name="TService">The service type that will be wrapped by the given
 /// <typeparamref name="TDecorator"/>.</typeparam>
 /// <typeparam name="TDecorator">The decorator type that will be used to wrap the original service type.</typeparam>
 /// <param name="lifestyle">The lifestyle that specifies how the returned decorator will be cached.</param>
 /// <exception cref="ArgumentNullException">Thrown when one of the arguments is a null reference.</exception>
 /// <exception cref="ArgumentException">Thrown when <typeparamref name="TDecorator"/>
 /// does not have a single public constructor, or when <typeparamref name="TDecorator"/> does
 /// not contain a constructor that has exactly one argument of type
 /// <typeparamref name="TService"/> or <see cref="Func{T}"/> where <b>T</b> is
 /// <typeparamref name="TService"/>.</exception>
 public void RegisterDecorator <TService, TDecorator>(Lifestyle lifestyle)
 {
     this.RegisterDecoratorCore(typeof(TService), typeof(TDecorator), lifestyle: lifestyle);
 }
 private static IServiceProvider GetServiceProviderForBackgroundThread(Container container, Lifestyle lifestyle) =>
 Lifestyle.Scoped.GetCurrentScope(container) != null
         ? container.GetInstance <IServiceScope>().ServiceProvider
         : throw new ActivationException(
           $"You are trying to resolve a {lifestyle.Name} cross-wired service, but are doing so outside the context " +
           $"of a web request. To be able to resolve this service, the operation must run in the context of an " +
           $"active ({container.Options.DefaultScopedLifestyle.Name}) scope.");
Esempio n. 8
0
        /// <summary>
        /// Registers all concrete, non-generic, public and internal types in the given set of
        /// <paramref name="assemblies"/> that implement the given <paramref name="openGenericServiceType"/>
        /// with the supplied <paramref name="lifestyle"/>.
        /// <see cref="TypesToRegisterOptions.IncludeDecorators">Decorators</see> and
        /// <see cref="TypesToRegisterOptions.IncludeGenericTypeDefinitions">generic type definitions</see>
        /// will be excluded from registration, while
        /// <see cref="TypesToRegisterOptions.IncludeComposites">composites</see> are included.
        /// </summary>
        /// <param name="openGenericServiceType">The definition of the open generic type.</param>
        /// <param name="assemblies">A list of assemblies that will be searched.</param>
        /// <param name="lifestyle">The lifestyle to register instances with.</param>
        /// <exception cref="ArgumentNullException">Thrown when one of the arguments contain a null
        /// reference (Nothing in VB).</exception>
        /// <exception cref="ArgumentException">Thrown when <paramref name="openGenericServiceType"/> is not
        /// an open generic type.</exception>
        /// <exception cref="InvalidOperationException">Thrown when the given set of
        /// <paramref name="assemblies"/> contain multiple types that implement the same
        /// closed generic version of the given <paramref name="openGenericServiceType"/>.</exception>
        public void Register(Type openGenericServiceType, IEnumerable <Assembly> assemblies, Lifestyle lifestyle)
        {
            Requires.IsNotNull(openGenericServiceType, nameof(openGenericServiceType));
            Requires.IsNotNull(lifestyle, nameof(lifestyle));
            Requires.IsNotNull(assemblies, nameof(assemblies));
            Requires.IsGenericType(openGenericServiceType, nameof(openGenericServiceType),
                                   guidance: StringResources.SuppliedTypeIsNotGenericExplainingAlternativesWithAssemblies);
            Requires.IsNotPartiallyClosed(openGenericServiceType, nameof(openGenericServiceType));
            Requires.IsOpenGenericType(openGenericServiceType, nameof(openGenericServiceType),
                                       guidance: StringResources.SuppliedTypeIsNotOpenGenericExplainingAlternativesWithAssemblies);

            Type[] skippedDecorators;

            Type[] implementationTypes = this.GetNonGenericTypesToRegisterForOneToOneMapping(
                openGenericServiceType, assemblies, out skippedDecorators);

            this.Register(openGenericServiceType, implementationTypes, lifestyle);

            this.AddSkippedDecorators(openGenericServiceType, skippedDecorators);
        }
Esempio n. 9
0
        /// <summary>
        /// Registers all supplied <paramref name="implementationTypes"/> based on the closed-generic version
        /// of the given <paramref name="openGenericServiceType"/> with the given <paramref name="lifestyle"/>.
        /// </summary>
        /// <param name="openGenericServiceType">The definition of the open generic type.</param>
        /// <param name="implementationTypes">A list types to be registered.</param>
        /// <param name="lifestyle">The lifestyle to register instances with.</param>
        /// <exception cref="ArgumentNullException">Thrown when one of the arguments contain a null
        /// reference (Nothing in VB).</exception>
        /// <exception cref="ArgumentException">Thrown when <paramref name="openGenericServiceType"/> is not
        /// an open generic type or when one of the supplied types from the
        /// <paramref name="implementationTypes"/> collection does not derive from
        /// <paramref name="openGenericServiceType"/>.</exception>
        /// <exception cref="InvalidOperationException">Thrown when the given set of
        /// <paramref name="implementationTypes"/> contain multiple types that implement the same
        /// closed generic version of the given <paramref name="openGenericServiceType"/>.</exception>
        public void Register(Type openGenericServiceType, IEnumerable <Type> implementationTypes, Lifestyle lifestyle)
        {
            Requires.IsNotNull(openGenericServiceType, nameof(openGenericServiceType));
            Requires.IsNotNull(lifestyle, nameof(lifestyle));
            Requires.IsNotNull(implementationTypes, nameof(implementationTypes));
            Requires.IsGenericType(openGenericServiceType, nameof(openGenericServiceType),
                                   guidance: StringResources.SuppliedTypeIsNotGenericExplainingAlternativesWithTypes);
            Requires.IsNotPartiallyClosed(openGenericServiceType, nameof(openGenericServiceType));
            Requires.IsOpenGenericType(openGenericServiceType, nameof(openGenericServiceType),
                                       guidance: StringResources.SuppliedTypeIsNotOpenGenericExplainingAlternativesWithTypes);

            implementationTypes = implementationTypes.Distinct().ToArray();

            Requires.DoesNotContainNullValues(implementationTypes, nameof(implementationTypes));
            Requires.CollectionDoesNotContainOpenGenericTypes(implementationTypes, nameof(implementationTypes));
            Requires.ServiceIsAssignableFromImplementations(openGenericServiceType, implementationTypes,
                                                            nameof(implementationTypes), typeCanBeServiceType: false);

            var mappings =
                from mapping in BatchMapping.Build(openGenericServiceType, implementationTypes)
                let registration = lifestyle.CreateRegistration(mapping.ImplementationType, this)
                                   from serviceType in mapping.ClosedServiceTypes
                                   select new { serviceType, registration };

            foreach (var mapping in mappings)
            {
                this.AddRegistration(mapping.serviceType, mapping.registration);
            }
        }
Esempio n. 10
0
        public static void RegisterEventHandlersFromAssemblyOf <T>(this Container container, Lifestyle lifestyle)
        {
            var assembly = typeof(T).GetTypeInfo().Assembly;

            RegisterEventHandlersFromAssembly(container, assembly, lifestyle);
        }
Esempio n. 11
0
 /// <summary>
 /// Ensures that the supplied <typeparamref name="TDecorator"/> decorator is returned and cached with
 /// the given <paramref name="lifestyle"/>, wrapping the original registered
 /// <typeparamref name="TService"/>, by injecting that service type into the constructor of the
 /// supplied <typeparamref name="TDecorator"/>. Multiple decorators may be applied to the same
 /// <typeparamref name="TService"/>. Decorators can be applied to both open, closed, and non-generic
 /// service types.
 /// </summary>
 /// <remarks>
 /// <para>
 /// The <b>RegisterDecorator</b> method works by hooking onto the container's
 /// <see cref="Container.ExpressionBuilt">ExpressionBuilt</see> event. This event fires after the
 /// <see cref="Container.ResolveUnregisteredType">ResolveUnregisteredType</see> event, which allows
 /// decoration of types that are resolved using unregistered type resolution.
 /// </para>
 /// <para>
 /// Multiple decorators can be applied to the same service type. The order in which they are registered
 /// is the order they get registered. This means that the decorator that gets registered first, gets
 /// applied first, which means that the next registered decorator, will wrap the first decorator, which
 /// wraps the original service type.
 /// </para>
 /// <para>
 /// Constructor injection will be used on that type, and although it may have many constructor
 /// arguments, it must have exactly one argument of the type of <typeparamref name="TService"/>, or an
 /// argument of type <see cref="Func{TResult}"/> where <b>TResult</b> is <typeparamref name="TService"/>.
 /// An exception will be thrown when this is not the case.
 /// </para>
 /// <para>
 /// The registered <typeparamref name="TDecorator"/> may have a constructor with an argument of type
 /// <see cref="Func{T}"/> where <b>T</b> is <typeparamref name="TService"/>. In this case, the
 /// will not inject the decorated <typeparamref name="TService"/> itself into the
 /// <typeparamref name="TDecorator"/> instance, but it will inject a <see cref="Func{T}"/> that allows
 /// creating instances of the decorated type, according to the lifestyle of that type. This enables
 /// more advanced scenarios, such as executing the decorated types on a different thread, or executing
 /// decorated instance within a certain scope (such as a lifetime scope).
 /// </para>
 /// </remarks>
 /// <example>
 /// Please see <see cref="RegisterDecorator(Type, Type)"/> for an example.
 /// </example>
 /// <typeparam name="TService">The service type that will be wrapped by the given
 /// <typeparamref name="TDecorator"/>.</typeparam>
 /// <typeparam name="TDecorator">The decorator type that will be used to wrap the original service type.</typeparam>
 /// <param name="lifestyle">The lifestyle that specifies how the returned decorator will be cached.</param>
 /// <exception cref="ArgumentNullException">Thrown when one of the arguments is a null reference.</exception>
 /// <exception cref="ArgumentException">Thrown when <typeparamref name="TDecorator"/>
 /// does not have a single public constructor, or when <typeparamref name="TDecorator"/> does
 /// not contain a constructor that has exactly one argument of type
 /// <typeparamref name="TService"/> or <see cref="Func{T}"/> where <b>T</b> is
 /// <typeparamref name="TService"/>.</exception>
 public void RegisterDecorator <TService, TDecorator>(Lifestyle lifestyle)
     where TService : class
     where TDecorator : class, TService
 {
     this.RegisterDecoratorCore(typeof(TService), typeof(TDecorator), lifestyle: lifestyle);
 }
Esempio n. 12
0
 private static IServiceProvider GetServiceProviderForBackgroundThread(
     Container container, Lifestyle lifestyle) =>
 Lifestyle.Scoped.GetCurrentScope(container) != null
         ? container.GetInstance <IServiceScope>().ServiceProvider
         : throw new ActivationException(
Esempio n. 13
0
        public static void RegisterCommandHandlersFromAssembly(this Container container, Assembly assembly, Lifestyle lifestyle)
        {
            if (lifestyle == null)
            {
                throw new ArgumentNullException(nameof(lifestyle));
            }

            var types = assembly.DefinedTypes.Where(x => x.IsClass && !x.IsAbstract && !x.IsGenericType &&
                                                    (
                                                        x.IsAssignableToGenericType(typeof(ICommandHandler <>)) ||
                                                        x.IsAssignableToGenericType(typeof(ICommandHandler <,>)) ||
                                                        x.IsAssignableToGenericType(typeof(IAsyncCommandHandler <>)) ||
                                                        x.IsAssignableToGenericType(typeof(IAsyncCommandHandler <,>))
                                                    ));

            foreach (var o in types.Select(t => new { Implementation = t, Services = t.ImplementedInterfaces }))
            {
                var type = o.Implementation.AsType();
                var attr = o.Implementation.GetCustomAttribute <LifetimeAttribute>();

                var registration = (attr?.Lifestyle ?? lifestyle).CreateRegistration(type, container);

                container.AddRegistration(type, registration);

                foreach (var serviceType in o.Services)
                {
                    container.AddRegistration(serviceType, registration);
                }
            }
        }
Esempio n. 14
0
 public static void RegisterCommandHandlersFromAssemblyOf <T>(this Container container, Lifestyle lifestyle)
 {
     RegisterCommandHandlersFromAssembly(container, typeof(T).GetTypeInfo().Assembly, lifestyle);
 }
Esempio n. 15
0
 public static void RegisterCqrsFromAssemblyOf <T>(this Container container, Lifestyle lifestyle)
 {
     RegisterCommandHandlersFromAssemblyOf <T>(container, lifestyle);
     RegisterQueryHandlersFromAssemblyOf <T>(container, lifestyle);
     RegisterEventHandlersFromAssemblyOf <T>(container, lifestyle);
 }
Esempio n. 16
0
        private void RegisterDecoratorCore(Type serviceType, Type decoratorType,
                                           Predicate <DecoratorPredicateContext> predicate = null, Lifestyle lifestyle = null)
        {
            Requires.IsNotNull(serviceType, nameof(serviceType));
            Requires.IsNotNull(decoratorType, nameof(decoratorType));

            Requires.ServiceTypeIsNotClosedWhenImplementationIsOpen(serviceType, decoratorType);
            Requires.ServiceOrItsGenericTypeDefinitionIsAssignableFromImplementation(serviceType, decoratorType, nameof(serviceType));
            Requires.ImplementationHasSelectableConstructor(this, serviceType, decoratorType, nameof(decoratorType));
            Requires.IsDecorator(this, serviceType, decoratorType, nameof(decoratorType));
            Requires.DecoratorIsNotAnOpenGenericTypeDefinitionWhenTheServiceTypeIsNot(serviceType, decoratorType, nameof(decoratorType));
            Requires.OpenGenericTypeDoesNotContainUnresolvableTypeArguments(serviceType, decoratorType, nameof(decoratorType));

            var interceptor = new DecoratorInterceptor(
                new DecoratorExpressionInterceptorData(
                    this, serviceType, decoratorType, predicate, lifestyle ?? this.SelectionBasedLifestyle));

            this.ExpressionBuilt += interceptor.ExpressionBuilt;
        }
Esempio n. 17
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);
                }
            };
        }
Esempio n. 18
0
        /// <summary>
        /// Registers all concrete, non-generic, public and internal types in the given set of
        /// <paramref name="assemblies"/> that implement the given <paramref name="openGenericServiceType"/>
        /// with the supplied <paramref name="lifestyle"/>.
        /// </summary>
        /// <param name="openGenericServiceType">The definition of the open generic type.</param>
        /// <param name="assemblies">A list of assemblies that will be searched.</param>
        /// <param name="lifestyle">The lifestyle to register instances with.</param>
        /// <exception cref="ArgumentNullException">Thrown when one of the arguments contain a null
        /// reference (Nothing in VB).</exception>
        /// <exception cref="ArgumentException">Thrown when <paramref name="openGenericServiceType"/> is not
        /// an open generic type.</exception>
        /// <exception cref="InvalidOperationException">Thrown when the given set of
        /// <paramref name="assemblies"/> contain multiple types that implement the same
        /// closed generic version of the given <paramref name="openGenericServiceType"/>.</exception>
        public void Register(Type openGenericServiceType, IEnumerable <Assembly> assemblies, Lifestyle lifestyle)
        {
            Requires.IsNotNull(openGenericServiceType, nameof(openGenericServiceType));
            Requires.IsNotNull(lifestyle, nameof(lifestyle));
            Requires.IsNotNull(assemblies, nameof(assemblies));
            Requires.IsGenericType(openGenericServiceType, nameof(openGenericServiceType),
                                   guidance: StringResources.SuppliedTypeIsNotGenericExplainingAlternativesWithAssemblies);
            Requires.IsNotPartiallyClosed(openGenericServiceType, nameof(openGenericServiceType));
            Requires.IsOpenGenericType(openGenericServiceType, nameof(openGenericServiceType),
                                       guidance: StringResources.SuppliedTypeIsNotOpenGenericExplainingAlternativesWithAssemblies);

            var implementationTypes = this.GetTypesToRegister(openGenericServiceType, assemblies);

            this.Register(openGenericServiceType, implementationTypes, lifestyle);
        }