private Expression BuildDecoratorEnumerableExpressionForNonConstantExpression( Delegate wrapInstanceWithDecorator, Expression expression) { // Build the query: from item in expression select wrapInstanceWithDecorator(item); var callExpression = DecoratorHelpers.Select(expression, this.registeredServiceType, wrapInstanceWithDecorator); if (this.Lifestyle == Lifestyle.Singleton) { Type enumerableServiceType = typeof(IEnumerable <>).MakeGenericType(this.registeredServiceType); Func <IEnumerable> collectionCreator = () => { Type funcType = typeof(Func <>).MakeGenericType(enumerableServiceType); Delegate lambda = Expression.Lambda(funcType, callExpression).Compile(); var decoratedCollection = (IEnumerable)lambda.DynamicInvoke(); Array array = ToArray(this.registeredServiceType, decoratedCollection); return(ExtensionHelpers.MakeReadOnly(this.registeredServiceType, array)); }; IEnumerable singleton = this.GetSingletonDecoratedCollection(collectionCreator); // Passing the enumerable type is needed when running in a (Silverlight) sandbox. return(Expression.Constant(singleton, enumerableServiceType)); } return(callExpression); }
private IDecoratableEnumerable BuildDecoratableEnumerable(IDecoratableEnumerable originalDecoratables, out IEnumerable <KnownRelationship> foundRelationships) { var contexts = ( from context in originalDecoratables.GetDecoratorPredicateContexts() let predicateIsSatisfied = this.SatisfiesPredicate(context) select new { IsDecorated = predicateIsSatisfied, OriginalContext = context, Context = predicateIsSatisfied ? this.DecorateContext(context) : context, }) .ToArray(); foundRelationships = ( from context in contexts where context.IsDecorated let dependency = context.OriginalContext.Registration let decoratorRegistration = context.Context.Registration.Registration from relationship in this.GetKnownDecoratorRelationships(decoratorRegistration, this.decoratorConstructor, this.registeredServiceType, dependency) select relationship) .ToArray(); var allContexts = contexts.Select(c => c.Context).ToArray(); return(DecoratorHelpers.CreateDecoratedEnumerable(this.registeredServiceType, this.Container, allContexts)); }
private void TryToApplyDecoratorOnContainerUncontrolledCollections(ExpressionBuiltEventArgs e) { if (!IsCollectionType(e.RegisteredServiceType) || DecoratorHelpers.IsContainerControlledCollectionExpression(e.Expression)) { // NOTE: Decorators on controlled collections will be applied by the normal mechanism. return; } var serviceType = e.RegisteredServiceType.GetGenericArguments()[0]; Type decoratorType; if (this.MustDecorate(serviceType, out decoratorType)) { this.ApplyDecoratorOnContainerUncontrolledCollection(e, decoratorType); } }
protected static ParameterInfo GetDecorateeParameter(Type serviceType, ConstructorInfo decoratorConstructor) { // Although we partly check for duplicate arguments during registration phase, we must do it here // as well, because some registrations are allowed while not all closed-generic implementations // can be resolved. var parameters = ( from parameter in decoratorConstructor.GetParameters() where DecoratorHelpers.IsDecorateeParameter(parameter.ParameterType, serviceType) select parameter) .ToArray(); if (parameters.Length > 1) { throw new ActivationException( StringResources.TypeDependsOnItself(decoratorConstructor.DeclaringType)); } return(parameters.Single()); }