Ejemplo n.º 1
0
        private InstanceProducer BuildInstanceProducerForMetadataList(Type enumerableOfProducersType)
        {
            Type metadataType = enumerableOfProducersType.GetGenericArguments()[0];
            Type serviceType  = metadataType.GetGenericArguments()[0];

            var collection = this.container.GetAllInstances(serviceType) as IContainerControlledCollection;

            if (collection is null)
            {
                // This exception might not be expressive enough. If GetAllInstances succeeds, but the
                // returned type is not an IContainerControlledCollection, it likely means the collection is
                // container uncontrolled.
                this.container.ThrowMissingInstanceProducerException(serviceType);
            }

            IContainerControlledCollection metadataCollection =
                ControlledCollectionHelper.CreateContainerControlledCollection(metadataType, this.container);

            metadataCollection.AppendAll(
                from producer in collection !.GetProducers()
                let metadata                     = CreateMetadata(metadataType, producer)
                                         let reg = Lifestyle.Singleton.CreateRegistration(metadataType, metadata, this.container)
                                                   select ContainerControlledItem.CreateFromRegistration(reg));

            return(new InstanceProducer(
                       serviceType: enumerableOfProducersType,
                       registration: metadataCollection.CreateRegistration(enumerableOfProducersType, this.container)));
        }
Ejemplo n.º 2
0
        private InstanceProducer BuildEmptyCollectionInstanceProducerForEnumerable(Type enumerableType)
        {
            Type elementType = enumerableType.GetGenericArguments()[0];

            var collection = ControlledCollectionHelper.CreateContainerControlledCollection(elementType, this);

            var registration = new ExpressionRegistration(Expression.Constant(collection, enumerableType), this);

            // Producers for ExpressionRegistration are normally ignored as external producer, but in this
            // case the empty collection producer should pop up in the list of GetCurrentRegistrations().
            return(new InstanceProducer(enumerableType, registration, registerExternalProducer: true));
        }
            // 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();
                }
            }
        private void TryToApplyDecoratorOnContainerUncontrolledCollections(ExpressionBuiltEventArgs e)
        {
            if (!IsCollectionType(e.RegisteredServiceType) ||
                ControlledCollectionHelper.IsContainerControlledCollectionExpression(e.Expression))
            {
                // NOTE: Decorators on controlled collections will be applied by the normal mechanism.
                return;
            }

            var serviceType = e.RegisteredServiceType.GetGenericArguments()[0];

            if (this.MustDecorate(serviceType, out Type? decoratorType))
            {
                this.ApplyDecoratorOnContainerUncontrolledCollection(e, decoratorType);
            }
        }
Ejemplo n.º 5
0
            // Implements #553 Allows detection of Lifestyle Mismatches when iterated inside constructor.
            private object Execute(Func<object> instanceCreator)
            {
                var isCurrentThread = new ThreadLocal<bool> { Value = true };

                // Create a listener that can spot when an injected stream is iterated during construction.
                var listener = this.CreateCollectionUsedDuringConstructionListener(isCurrentThread);

                try
                {
                    ControlledCollectionHelper.AddServiceCreatedListener(listener);

                    return instanceCreator();
                }
                finally
                {
                    ControlledCollectionHelper.RemoveServiceCreatedListener(listener);
                    isCurrentThread.Dispose();
                }
            }