// Implements #553
            private TImplementation CreateInstance(Func <TImplementation> instanceCreator)
            {
                var isCurrentThread = new ThreadLocal <bool> {
                    Value = true
                };

                // Create a listener that can spot when an injected stream is iterated during construction.
                Action <ServiceCreatedListenerArgs> listener = args =>
                {
                    // Only handle when an inner registration hasn't handled this yet.
                    if (!args.Handled)
                    {
                        // Only handle when the call originates from the same thread, as calls from different
                        // threads mean the listener is not triggered from this specific instanceCreator.
                        if (isCurrentThread.Value)
                        {
                            args.Handled = true;
                            var matchingRelationship = this.FindMatchingCollectionRelationship(args.Producer);

                            var additionalInformation = StringResources.CollectionUsedDuringConstruction(
                                typeof(TImplementation),
                                args.Producer,
                                matchingRelationship);

                            // At this point, an injected ContainerControlledCollection<T> has notified the
                            // listener about the creation of one of its elements. This has happened during
                            // the construction of this (Singleton) instance, which might cause Lifestyle
                            // Mismatches. That's why this is added as a known relationship. This way
                            // diagnostics can verify the relationship.
                            this.AddRelationship(
                                new KnownRelationship(
                                    implementationType: typeof(TImplementation),
                                    lifestyle: this.Lifestyle,
                                    consumer: matchingRelationship?.Consumer ?? InjectionConsumerInfo.Root,
                                    dependency: args.Producer,
                                    additionalInformation: additionalInformation));
                        }
                    }
                };

                try
                {
                    ControlledCollectionHelper.AddServiceCreatedListener(listener);

                    return(instanceCreator());
                }
                finally
                {
                    ControlledCollectionHelper.RemoveServiceCreatedListener(listener);
                    isCurrentThread.Dispose();
                }
            }
Beispiel #2
0
            private Action <ServiceCreatedListenerArgs> CreateCollectionUsedDuringConstructionListener(
                ThreadLocal <bool> isCurrentThread)
            {
                return(args =>
                {
                    // Only handle when an inner registration hasn't handled this yet.
                    if (!args.Handled)
                    {
                        // Only handle when the call originates from the same thread, as calls from different
                        // threads mean the listener is not triggered from this specific instanceCreator.
                        if (isCurrentThread.Value)
                        {
                            args.Handled = true;
                            var matchingRelationship = this.FindMatchingCollectionRelationship(args.Producer);

                            var additionalInformation = StringResources.CollectionUsedDuringConstruction(
                                this.ImplementationType,
                                args.Producer,
                                matchingRelationship);

                            // At this point, an injected ContainerControlledCollection<T> has notified the
                            // listener about the creation of one of its elements. This has happened during
                            // the construction of this (Singleton) instance, which might cause Lifestyle
                            // Mismatches. That's why this is added as a known relationship. This way
                            // diagnostics can verify the relationship.
                            var relationship = new KnownRelationship(
                                implementationType: this.ImplementationType,
                                lifestyle: this.Lifestyle,
                                consumer: matchingRelationship?.Consumer ?? InjectionConsumerInfo.Root,
                                dependency: args.Producer);

                            relationship.AddAdditionalInformation(
                                DiagnosticType.LifestyleMismatch, additionalInformation);

                            this.AddRelationship(relationship);
                        }
                    }
                });
            }