Example #1
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.IsNotPartiallyClosed(serviceType, nameof(serviceType));
            Requires.ServiceTypeIsNotClosedWhenImplementationIsOpen(serviceType, decoratorType);
            Requires.ServiceOrItsGenericTypeDefinitionIsAssignableFromImplementation(
                serviceType, decoratorType, nameof(serviceType));

            Requires.ImplementationHasSelectableConstructor(this, 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;
        }
Example #2
0
        /// <summary>
        /// Conditionally registers that an instance of <paramref name="implementationType"/> will be
        /// returned every time a <paramref name="serviceType"/> is requested and where the supplied
        /// <paramref name="predicate"/> returns true. The instance is cached according to the supplied
        /// <paramref name="lifestyle"/>. The predicate will only be evaluated a finite number of times; the
        /// predicate is unsuited for making decisions based on runtime conditions.
        /// </summary>
        /// <param name="serviceType">The base type or interface to register. This can be an open-generic type.</param>
        /// <param name="implementationType">The actual type that will be returned when requested.</param>
        /// <param name="lifestyle">The lifestyle that defines how returned instances are cached.</param>
        /// <param name="predicate">The predicate that determines whether the
        /// <paramref name="implementationType"/> can be applied for the requested service type. This predicate
        /// can be used to build a fallback mechanism where multiple registrations for the same service type
        /// are made. Note that the predicate will be called a finite number of times and its result will be cached
        /// for the lifetime of the container. It can't be used for selecting a type based on runtime conditions.
        /// </param>
        /// <exception cref="ArgumentNullException">Thrown when one of the arguments is a null reference
        /// (Nothing in VB).</exception>
        /// <exception cref="ArgumentException">Thrown when <paramref name="serviceType"/> and
        /// <paramref name="implementationType"/> are not a generic type or when <paramref name="serviceType"/>
        /// is a partially-closed generic type.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Thrown when this container instance is locked and can not be altered.
        /// </exception>
        public void RegisterConditional(
            Type serviceType,
            Type implementationType,
            Lifestyle lifestyle,
            Predicate <PredicateContext> predicate)
        {
            Requires.IsNotNull(serviceType, nameof(serviceType));
            Requires.IsNotNull(implementationType, nameof(implementationType));
            Requires.IsNotNull(lifestyle, nameof(lifestyle));
            Requires.IsNotNull(predicate, nameof(predicate));
            Requires.IsNotPartiallyClosed(serviceType, nameof(serviceType), nameof(implementationType));

            Requires.ServiceOrItsGenericTypeDefinitionIsAssignableFromImplementation(
                serviceType, implementationType, nameof(serviceType));

            Requires.ImplementationHasSelectableConstructor(
                this, implementationType, nameof(implementationType));

            Requires.OpenGenericTypeDoesNotContainUnresolvableTypeArguments(
                serviceType, implementationType, nameof(implementationType));

            if (serviceType.ContainsGenericParameters())
            {
                this.RegisterOpenGeneric(serviceType, implementationType, lifestyle, predicate);
            }
            else
            {
                var registration = lifestyle.CreateRegistration(implementationType, this);
                this.RegisterConditional(serviceType, registration, predicate);
            }
        }