コード例 #1
0
        private static string BuildRelationshipDescription(KnownRelationship relationship)
        {
            string additionalInformation1 =
                relationship.GetAdditionalInformation(DiagnosticType.LifestyleMismatch);

            string additionalInformation2 =
                relationship.Dependency.Registration is ScopedRegistration scoped
                ? scoped.AdditionalInformationForLifestyleMismatchDiagnostics
                : string.Empty;

            return(string.Format(
                       CultureInfo.InvariantCulture,
                       "{0} ({1}) depends on {2}{3} ({4}).{5}{6}{7}{8}",
                       relationship.ImplementationType.FriendlyName(),
                       relationship.Lifestyle.Name,
                       relationship.Dependency.ServiceType.FriendlyName(),
                       relationship.Dependency.ServiceType != relationship.Dependency.FinalImplementationType
                    ? " implemented by " + relationship.Dependency.FinalImplementationType.FriendlyName()
                    : string.Empty,
                       relationship.Dependency.Lifestyle.Name,
                       additionalInformation1 == string.Empty ? string.Empty : " ",
                       additionalInformation1,
                       additionalInformation2 == string.Empty ? string.Empty : " ",
                       additionalInformation2));
        }
コード例 #2
0
        public void KnownRelationships_InsertingNullValue_ThrowsExpectedException()
        {
            // Arrange
            KnownRelationship invalidRelationship = null;

            var container = ContainerFactory.New();

            container.Register <IUserRepository, SqlUserRepository>();
            container.Register <FakeUserService>();

            container.ExpressionBuilt += (s, e) =>
            {
                if (e.RegisteredServiceType == typeof(FakeUserService))
                {
                    Assert.AreEqual(1, e.KnownRelationships.Count, "Test setup failed.");

                    // Assert
                    AssertThat.Throws <ArgumentNullException>(
                        () => e.KnownRelationships.Insert(0, invalidRelationship));
                }
            };

            // Act
            container.GetInstance <FakeUserService>();
        }
コード例 #3
0
 internal LifestyleMismatchDiagnosticResult(Type serviceType, string description,
     KnownRelationship relationship)
     : base(serviceType, description, DiagnosticType.LifestyleMismatch,
         DiagnosticSeverity.Warning, relationship)
 {
     this.Relationship = relationship;
 }
コード例 #4
0
        private static string BuildDescription(InstanceProducer registration, KnownRelationship[] relationships)
        {
            string componentName = BuildComponentName(registration, relationships);
            string unregisteredTypeName = BuildUnregisteredTypeDescription(relationships);

            return componentName + " depends on " + unregisteredTypeName + ".";
        }
コード例 #5
0
        internal static bool HasLifestyleMismatch(Container container, KnownRelationship relationship)
        {
            Lifestyle componentLifestyle  = relationship.Lifestyle;
            Lifestyle dependencyLifestyle = relationship.Dependency.Lifestyle;

            // If the lifestyles are the same instance, we consider them valid, even though in theory
            // an hybrid lifestyle could screw things up. In practice this would be very unlikely, since
            // the Func<bool> test delegate would typically return the same value within a given context.
            if (object.ReferenceEquals(componentLifestyle, dependencyLifestyle) &&
                componentLifestyle != Lifestyle.Unknown)
            {
                return(false);
            }

            var componentLength = componentLifestyle.ComponentLength(container);

            if (container.Options.UseLoosenedLifestyleMismatchBehavior &&
                componentLength <= Lifestyle.Scoped.Length)
            {
                return(false);
            }

            var dependencyLength = dependencyLifestyle.DependencyLength(container);

            return(componentLength > dependencyLength);
        }
コード例 #6
0
 internal LifestyleMismatchDiagnosticResult(Type serviceType, string description,
                                            KnownRelationship relationship)
     : base(serviceType, description, DiagnosticType.LifestyleMismatch,
            DiagnosticSeverity.Warning, relationship)
 {
     this.Relationship = relationship;
 }
コード例 #7
0
 private KnownRelationship ReplaceLifestyle(KnownRelationship relationship)
 {
     return(new KnownRelationship(
                relationship.ImplementationType,
                this.Lifestyle,
                relationship.Dependency));
 }
コード例 #8
0
        public void GetRelationship_OnRegistrationBuiltByRegisterAllOpenGeneric_ReturnsTheExpectedRelationships()
        {
            // Arrange
            var container = ContainerFactory.New();

            container.RegisterSingle <ILogger, FakeLogger>();

            container.RegisterAllOpenGeneric(typeof(IEventHandler <>), typeof(EventHandlerWithLoggerDependency <>));

            container.Register <ServiceWithDependency <IEnumerable <IEventHandler <ClassEvent> > > >();

            container.Verify();

            var expectedRelationship = new KnownRelationship(
                implementationType: typeof(EventHandlerWithLoggerDependency <ClassEvent>),
                lifestyle: Lifestyle.Transient,
                dependency: container.GetRegistration(typeof(ILogger)));

            // Act
            var actualRelationship =
                container.GetRegistration(typeof(IEnumerable <IEventHandler <ClassEvent> >)).GetRelationships()
                .Single();

            // Assert
            Assert.AreEqual(expectedRelationship.ImplementationType, actualRelationship.ImplementationType);
            Assert.AreEqual(expectedRelationship.Lifestyle, actualRelationship.Lifestyle);
            Assert.AreEqual(expectedRelationship.Dependency, actualRelationship.Dependency);
        }
コード例 #9
0
 private KnownRelationship ReplaceLifestyle(KnownRelationship relationship) =>
 new KnownRelationship(
     relationship.ImplementationType,
     this.Lifestyle,
     relationship.Consumer,
     relationship.Dependency,
     relationship.AdditionalInformation);
 private static ContainerRegisteredServiceDiagnosticResult BuildDiagnosticResult(
     InstanceProducer registration, KnownRelationship[] relationships)
 {
     return new ContainerRegisteredServiceDiagnosticResult(
         serviceType: registration.ServiceType,
         description: BuildDescription(registration, relationships),
         relationships: relationships);
 }
コード例 #11
0
        internal void AddRelationship(KnownRelationship relationship)
        {
            Requires.IsNotNull(relationship, "relationship");

            lock (this.dependencies)
            {
                this.dependencies.Add(relationship);
            }
        }
コード例 #12
0
        internal void AddRelationship(KnownRelationship relationship)
        {
            Requires.IsNotNull(relationship, nameof(relationship));

            lock (this.knownRelationships)
            {
                this.knownRelationships.Add(relationship);
            }
        }
コード例 #13
0
 private static string BuildRelationshipDescription(KnownRelationship relationship)
 {
     return(string.Format(CultureInfo.InvariantCulture,
                          "{0} ({1}) depends on {2} ({3}).",
                          Helpers.ToFriendlyName(relationship.ImplementationType),
                          relationship.Lifestyle.Name,
                          Helpers.ToFriendlyName(relationship.Dependency.ServiceType),
                          relationship.Dependency.Lifestyle.Name));
 }
コード例 #14
0
 private static string BuildRelationshipDescription(KnownRelationship relationship) =>
 string.Format(CultureInfo.InvariantCulture,
               "{0} ({1}) depends on {2}{3} ({4}).",
               relationship.ImplementationType.ToFriendlyName(),
               relationship.Lifestyle.Name,
               relationship.Dependency.ServiceType.ToFriendlyName(),
               relationship.Dependency.ServiceType != relationship.Dependency.ImplementationType
             ? " implemented by " + relationship.Dependency.ImplementationType.ToFriendlyName()
             : string.Empty,
               relationship.Dependency.Lifestyle.Name);
コード例 #15
0
 private static string BuildRelationshipDescription(KnownRelationship relationship) => 
     string.Format(CultureInfo.InvariantCulture,
         "{0} ({1}) depends on {2}{3} ({4}).",
         Helpers.ToFriendlyName(relationship.ImplementationType),
         relationship.Lifestyle.Name,
         Helpers.ToFriendlyName(relationship.Dependency.ServiceType),
         relationship.Dependency.ServiceType != relationship.Dependency.ImplementationType
             ? " implemented by " + Helpers.ToFriendlyName(relationship.Dependency.ImplementationType)
             : string.Empty,
         relationship.Dependency.Lifestyle.Name);
コード例 #16
0
 internal ShortCircuitedDependencyDiagnosticResult(Type serviceType, string description,
     InstanceProducer registration, KnownRelationship relationship,
     IEnumerable<InstanceProducer> expectedDependencies)
     : base(serviceType, description, DiagnosticType.ShortCircuitedDependency, 
         DiagnosticSeverity.Warning, 
         CreateDebugValue(registration, relationship, expectedDependencies.ToArray()))
 {
     this.Relationship = relationship;
     this.ExpectedDependencies = new ReadOnlyCollection<InstanceProducer>(expectedDependencies.ToList());
 }
コード例 #17
0
        internal static bool HasLifestyleMismatch(Container container, KnownRelationship relationship)
        {
            Lifestyle componentLifestyle = relationship.Lifestyle;
            Lifestyle dependencyLifestyle = relationship.Dependency.Lifestyle;

            // If the lifestyles are the same instance, we consider them valid, even though in theory
            // an hybrid lifestyle could screw things up. In practice this would be very unlikely, since
            // the Func<bool> test delegate would typically return the same value within a given context.
            if (object.ReferenceEquals(componentLifestyle, dependencyLifestyle) &&
                componentLifestyle != Lifestyle.Unknown)
            {
                return false;
            }

            return componentLifestyle.ComponentLength(container) > dependencyLifestyle.DependencyLength(container);
        }
コード例 #18
0
        internal static bool HasPossibleLifestyleMismatch(KnownRelationship relationship)
        {
            Lifestyle componentLifestyle  = relationship.Lifestyle;
            Lifestyle dependencyLifestyle = relationship.Dependency.Lifestyle;

            // If the lifestyles are the same instance, we consider them valid, even though in theory
            // an hybrid lifestyle could screw things up. In practice this would be very unlikely, since
            // the Func<bool> test delegate would typically return the same value within a given context.
            if (object.ReferenceEquals(componentLifestyle, dependencyLifestyle) &&
                componentLifestyle != Lifestyle.Unknown)
            {
                return(false);
            }

            return(componentLifestyle.ComponentLength > dependencyLifestyle.DependencyLength);
        }
コード例 #19
0
        public void KnownRelationships_AddingNullValue_ThrowsExpectedException()
        {
            // Arrange
            KnownRelationship invalidRelationship = null;

            var container = ContainerFactory.New();

            container.ExpressionBuilt += (s, e) =>
            {
                // Assert
                AssertThat.Throws <ArgumentNullException>(() => e.KnownRelationships.Add(invalidRelationship));
            };

            // Act
            container.GetInstance <SqlUserRepository>();
        }
コード例 #20
0
        private static string BuildDescription(KnownRelationship relationship,
                                               IEnumerable <InstanceProducer> possibleSkippedRegistrations)
        {
            var possibleSkippedRegistrationsDescription = string.Join(" or ",
                                                                      from possibleSkippedRegistration in possibleSkippedRegistrations
                                                                      let name = possibleSkippedRegistration.ServiceType.ToFriendlyName()
                                                                                 orderby name
                                                                                 select string.Format(CultureInfo.InvariantCulture, "{0} ({1})",
                                                                                                      name, possibleSkippedRegistration.Lifestyle.Name));

            return(string.Format(CultureInfo.InvariantCulture,
                                 "{0} might incorrectly depend on unregistered type {1} ({2}) instead of {3}.",
                                 relationship.ImplementationType.ToFriendlyName(),
                                 relationship.Dependency.ServiceType.ToFriendlyName(),
                                 relationship.Dependency.Lifestyle.Name,
                                 possibleSkippedRegistrationsDescription));
        }
コード例 #21
0
        protected InstanceProducer CreateDecorateeFactoryProducer(
            ParameterInfo parameter, InstanceProducer decorateeProducer)
        {
            // We create a dummy expression with a null value. Much easier than passing on the real delegate.
            // We won't miss it, since the created InstanceProducer is just a dummy for purposes of analysis.
            var dummyExpression = Expression.Constant(null, parameter.ParameterType);

            var registration = new ExpressionRegistration(dummyExpression, this.Container);

            var relationship = new KnownRelationship(
                parameter.ParameterType, Lifestyle.Singleton, decorateeProducer)
            {
                // Make sure the relationship is not traversed when doing verification, because that leads to
                // false positivies.
                UseForVerification = false
            };

            registration.AddRelationship(relationship);

            return(new InstanceProducer(parameter.ParameterType, registration));
        }
 private static DebuggerViewItem[] CreateDebugValue(InstanceProducer registration,
     KnownRelationship actualDependency, 
     InstanceProducer[] possibleSkippedRegistrations)
 {
     return new[]
     {
         new DebuggerViewItem(
             name: "Registration", 
             description: registration.ServiceType.ToFriendlyName(), 
             value: registration),
         new DebuggerViewItem(
             name: "Actual Dependency", 
             description: actualDependency.Dependency.ServiceType.ToFriendlyName(), 
             value: actualDependency),
         new DebuggerViewItem(
             name: "Expected Dependency", 
             description: possibleSkippedRegistrations.First().ServiceType.ToFriendlyName(),
             value: possibleSkippedRegistrations.Length == 1 ? 
                 (object)possibleSkippedRegistrations[0] : 
                 possibleSkippedRegistrations),
     };
 }
 private static DebuggerViewItem[] CreateDebugValue(InstanceProducer registration,
                                                    KnownRelationship actualDependency,
                                                    InstanceProducer[] possibleSkippedRegistrations)
 {
     return(new[]
     {
         new DebuggerViewItem(
             name: "Registration",
             description: registration.ServiceType.ToFriendlyName(),
             value: registration),
         new DebuggerViewItem(
             name: "Actual Dependency",
             description: actualDependency.Dependency.ServiceType.ToFriendlyName(),
             value: actualDependency),
         new DebuggerViewItem(
             name: "Expected Dependency",
             description: possibleSkippedRegistrations[0].ServiceType.ToFriendlyName(),
             value: possibleSkippedRegistrations.Length == 1 ?
             (object)possibleSkippedRegistrations[0] :
             possibleSkippedRegistrations),
     });
 }
コード例 #24
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);
                        }
                    }
                });
            }
コード例 #25
0
 private static bool HasPossibleLifestyleMismatch(KnownRelationship dependency) =>
 LifestyleMismatchChecker.HasLifestyleMismatch(new Container(), dependency);
 internal PotentialLifestyleMismatchDiagnosticResult(Type serviceType, string description,
                                                     KnownRelationship relationship)
     : base(serviceType, description, DiagnosticType.PotentialLifestyleMismatch, relationship)
 {
     this.Relationship = relationship;
 }
コード例 #27
0
 private KnownRelationship ReplaceLifestyle(KnownRelationship relationship) => 
     new KnownRelationship(
         relationship.ImplementationType,
         this.Lifestyle,
         relationship.Dependency);
        private void MarkDecorateeFactoryRelationshipAsInstanceCreationDelegate(
            KnownRelationship[] relationships)
        {
            var decorateeFactoryDependencies = this.GetDecorateeFactoryDependencies(relationships);

            foreach (Registration dependency in decorateeFactoryDependencies)
            {
                // Mark the dependency of the decoratee factory
                dependency.WrapsInstanceCreationDelegate = true;
            }
        }
 private IEnumerable<Registration> GetDecorateeFactoryDependencies(KnownRelationship[] relationships) => 
     from relationship in relationships
     where DecoratorHelpers.IsDecorateeFactoryDependencyParameter(
         relationship.Dependency.ServiceType, this.e.RegisteredServiceType)
     select relationship.Dependency.Registration;
コード例 #30
0
 private static bool HasPossibleLifestyleMismatch(
     KnownRelationship dependency, bool?useLoosenedLifestyleMismatchBehavior = null) =>
 LifestyleMismatchChecker.HasLifestyleMismatch(
     CreateContainer(useLoosenedLifestyleMismatchBehavior),
     dependency);
コード例 #31
0
        private static string BuildDescription(KnownRelationship relationship,
            IEnumerable<InstanceProducer> possibleSkippedRegistrations)
        {
            var possibleSkippedRegistrationsDescription = string.Join(" or ",
                from possibleSkippedRegistration in possibleSkippedRegistrations
                let name = possibleSkippedRegistration.ServiceType.ToFriendlyName()
                orderby name
                select string.Format(CultureInfo.InvariantCulture, "{0} ({1})",
                    name, possibleSkippedRegistration.Lifestyle.Name));

            return string.Format(CultureInfo.InvariantCulture,
                "{0} might incorrectly depend on unregistered type {1} ({2}) instead of {3}.",
                relationship.ImplementationType.ToFriendlyName(),
                relationship.Dependency.ServiceType.ToFriendlyName(),
                relationship.Dependency.Lifestyle.Name,
                possibleSkippedRegistrationsDescription);
        }
コード例 #32
0
        private static string BuildComponentName(InstanceProducer registration, KnownRelationship[] relationships)
        {
            var consumingTypes = (
                from relationship in relationships
                select relationship.ImplementationType)
                .Distinct()
                .ToArray();

            if (consumingTypes.Length == 1)
            {
                return consumingTypes.First().ToFriendlyName();
            }
            else
            {
                return registration.ServiceType.ToFriendlyName();
            }
        }
コード例 #33
0
        private static string BuildUnregisteredTypeDescription(KnownRelationship[] relationships)
        {
            var unregisteredTypes = (
                from relationship in relationships
                select relationship.Dependency.ServiceType)
                .Distinct()
                .ToArray();

            if (unregisteredTypes.Length == 1)
            {
                return "container-registered type " + unregisteredTypes[0].ToFriendlyName();
            }
            else
            {
                return unregisteredTypes.Length + " container-registered types";
            }
        }