private Expression BuildDecoratorExpression(IDecoratableEnumerable collection, out IEnumerable <KnownRelationship> foundRelationships) { foundRelationships = Enumerable.Empty <KnownRelationship>(); // When we're dealing with a Singleton decorator, we must cache the list, because other theads // could create another 'singleton' instance of this decorator. But since this list is at this // point currently just a list of Expressions (returned as constant), we can always cache this // list, even if the decorator is transient. This cache is an instance list, since it is specific // to the current decorator registration. lock (this.decoratableEnumerablesCache) { IDecoratableEnumerable decoratedCollection; if (!this.decoratableEnumerablesCache.TryGetValue(this.registeredServiceType, out decoratedCollection)) { decoratedCollection = this.BuildDecoratableEnumerable(collection, out foundRelationships); this.decoratableEnumerablesCache[this.registeredServiceType] = decoratedCollection; } return(Expression.Constant(decoratedCollection)); } }
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)); }