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; }
/// <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); } }