예제 #1
0
        public void Analyze_ConfigurationWithCollectionWithMultipleDecoratorsWithValidNumberOfDependencies_DoesNotWarnAboutThatDecorator()
        {
            // Arrange
            Container container = CreateContainerWithRegistrations(Type.EmptyTypes);

            container.RegisterDecorator(typeof(IPlugin), typeof(PluginDecoratorWith5Dependencies));
            container.RegisterDecorator(typeof(IPlugin), typeof(PluginDecoratorWith5Dependencies));
            container.RegisterDecorator(typeof(IPlugin), typeof(PluginDecoratorWith5Dependencies));

            // Non of these types have too many dependencies.
            container.RegisterCollection <IPlugin>(new[] { typeof(PluginImpl), typeof(SomePluginImpl) });

            container.Verify();

            // Act
            var results = DebuggerGeneralWarningsContainerAnalyzer.Analyze(container);

            // Assert
            Assert.AreEqual("No warnings detected.", results.Description, @"
                Although the decorator has too many dependencies, the system has not enough information to
                differentiate between a decorator with too many dependencies and a decorator that wraps many
                elements. The diagnostic system simply registers all dependencies that this decorator has,
                and all elements it decorates are a dependency and its hard to see the real number of
                dependencies it has. Because of this, we have to suppress violations on collections
                completely.");
        }
예제 #2
0
        public void Analyze_WithInvalidConfiguration_ReturnsResultsWithExpectedViolationInformation()
        {
            // Arrange
            var expectedImplementationTypeInformation = new DebuggerViewItem(
                name: "ImplementationType",
                description: typeof(PluginWith8Dependencies).Name,
                value: typeof(PluginWith8Dependencies));

            var expectedDependenciesInformation = new DebuggerViewItem(
                name: "Dependencies",
                description: "8 dependencies.",
                value: null);

            Container container = CreateContainerWithRegistrations(typeof(PluginWith8Dependencies));

            container.Verify();

            // Act
            var results = DebuggerGeneralWarningsContainerAnalyzer.Analyze(container).Value as DebuggerViewItem[];

            var result = results.Single();

            var violationInformation = result.Value as DebuggerViewItem[];

            // Assert
            Assert_AreEqual(expectedImplementationTypeInformation, violationInformation[0]);
            Assert_AreEqual(expectedDependenciesInformation, violationInformation[1], validateValue: false);
        }
        public void Analyze_OnConfigurationWithOneShortCircuitedRegistrationWithTwoPossibleSolutions_ReturnsThatWarning()
        {
            // Arrange
            var container = new Container();

            var registration = Lifestyle.Singleton.CreateRegistration <ImplementsBothInterfaces>(container);

            container.AddRegistration(typeof(IService1), registration);
            container.AddRegistration(typeof(IService2), registration);

            container.Register <Controller <int> >();

            container.Verify(VerificationOption.VerifyOnly);

            // Act
            var results = GetShortCircuitedResults(DebuggerGeneralWarningsContainerAnalyzer.Analyze(container));

            // Assert
            Assert.AreEqual(1, results.Length);
            Assert.AreEqual(typeof(Controller <int>).ToFriendlyName(), results[0].Name);
            Assert.AreEqual(
                "Controller<Int32> might incorrectly depend on unregistered type ImplementsBothInterfaces " +
                "(Transient) instead of IService1 (Singleton) or IService2 (Singleton).",
                results[0].Description);
        }
        public void Analyze_ShortCircuitedRegistrationWithMultipleTypesInOneGroup_ReportsExpectedWarning()
        {
            // Arrange
            var container = new Container();

            var registration = Lifestyle.Singleton.CreateRegistration <ImplementsBothInterfaces>(container);

            container.AddRegistration(typeof(IService1), registration);
            container.AddRegistration(typeof(IService2), registration);

            // Two types in same group
            container.Register <Controller <int> >();
            container.Register <Controller <float> >();

            container.Verify(VerificationOption.VerifyOnly);

            // Act
            var results = GetShortCircuitedResults(DebuggerGeneralWarningsContainerAnalyzer.Analyze(container)).Single();

            // Assert
            Assert.AreEqual("Controller<T>", results.Name);
            Assert.AreEqual("2 short circuited components.", results.Description);
            AssertThat.IsInstanceOfType(typeof(DebuggerViewItem[]), results.Value);
            Assert.AreEqual(2, ((DebuggerViewItem[])results.Value).Length);
        }
        public void Analyze_OnConfigurationWithOneShortCircuitedRegistration_ReturnsThatWarning()
        {
            // Arrange
            var container = new Container();

            container.Options.ResolveUnregisteredConcreteTypes = true;

            container.Register <IUnitOfWork, MyUnitOfWork>(Lifestyle.Singleton);

            // HomeController depends on MyUnitOfWork.
            container.Register <HomeController>();

            container.Verify(VerificationOption.VerifyOnly);

            // Act
            var results = GetShortCircuitedResults(DebuggerGeneralWarningsContainerAnalyzer.Analyze(container));

            // Assert
            Assert.AreEqual(1, results.Length);
            Assert.AreEqual("HomeController", results[0].Name);
            Assert.AreEqual(
                "HomeController might incorrectly depend on unregistered type MyUnitOfWork " +
                "(Transient) instead of IUnitOfWork (Singleton).",
                results[0].Description);
        }
예제 #6
0
        public void Analyze_OnConfigurationWithMultipleViolations_ReturnsThoseTwoViolations()
        {
            // Arrange
            Container container = CreateContainerWithRegistrations(
                typeof(PluginWith8Dependencies),
                typeof(AnotherPluginWith8Dependencies));

            container.Verify();

            // Act
            var results = DebuggerGeneralWarningsContainerAnalyzer.Analyze(container).Value as DebuggerViewItem[];

            // Assert
            Assert.AreEqual(2, results.Length);

            var plugin1 = results.Single(r => r.Name == typeof(PluginWith8Dependencies).Name);

            Assert.AreEqual(
                typeof(PluginWith8Dependencies).Name + " has 8 dependencies which might indicate a SRP violation.",
                plugin1.Description);

            var plugin2 = results.Single(r => r.Name == typeof(AnotherPluginWith8Dependencies).Name);

            Assert.AreEqual(
                typeof(AnotherPluginWith8Dependencies).Name +
                " has 8 dependencies which might indicate a SRP violation.",
                plugin2.Description);
        }
예제 #7
0
        public void Analyze_OnEmptyConfiguration_ReturnsNull()
        {
            // Arrange
            var container = new Container();

            container.Verify();

            // Act
            var results = DebuggerGeneralWarningsContainerAnalyzer.Analyze(container);

            // Assert
            Assert.AreEqual("No warnings detected.", results.Description);
        }
예제 #8
0
        public void Analyze_OnValidConfiguration_ReturnsNull()
        {
            // Arrange
            Container container = CreateContainerWithRegistrations(typeof(PluginWith7Dependencies));

            container.Verify();

            // Act
            var results = DebuggerGeneralWarningsContainerAnalyzer.Analyze(container);

            // Assert
            Assert.AreEqual("No warnings detected.", results.Description,
                            "6 dependencies is still considered valid (to prevent too many false positives).");
        }
        public void Analyze_ShortCiruitedRegistrationWithSameLifestyle_ReportsExpectedWarning()
        {
            // Arrange
            var container = new Container();

            container.Register <ILogger, NullLogger>();
            container.Register <ServiceDependingOn <NullLogger> >();

            container.Verify(VerificationOption.VerifyOnly);

            // Act
            var results = GetShortCircuitedResults(DebuggerGeneralWarningsContainerAnalyzer.Analyze(container)).Single();

            // Assert
            Assert.AreEqual("ServiceDependingOn<NullLogger>", results.Name);
        }
예제 #10
0
        public void Analyze_ConfigurationWithViolation_ReturnsTheExpectedDebuggerViewItems()
        {
            // Arrange
            var container = new Container();

            container.Register <IFoo, FooBar>(Lifestyle.Singleton);
            container.Register <IBar, FooBar>(Lifestyle.Singleton);

            container.Verify();

            // Act
            var results = DebuggerGeneralWarningsContainerAnalyzer.Analyze(container).Value as DebuggerViewItem[];

            // Assert
            Assert.AreEqual(typeof(IBar).Name, results[0].Name);
            Assert.AreEqual(typeof(IFoo).Name, results[1].Name);
        }
예제 #11
0
        public void Analyze_OnConfigurationWithOneViolation_ReturnsThatViolation()
        {
            // Arrange
            Container container = CreateContainerWithRegistrations(typeof(PluginWith8Dependencies));

            container.Verify();

            // Act
            var results = DebuggerGeneralWarningsContainerAnalyzer.Analyze(container).Value as DebuggerViewItem[];

            // Assert
            Assert.AreEqual(1, results.Length);
            Assert.AreEqual(typeof(PluginWith8Dependencies).Name, results[0].Name);
            Assert.AreEqual(typeof(PluginWith8Dependencies).Name +
                            " has 8 dependencies which might indicate a SRP violation.",
                            results[0].Description);
        }
예제 #12
0
        public void Analyze_ContainerWithOneMismatch_ReturnsItemWithExpectedDescription()
        {
            // Arrange
            var container = new Container();

            container.Register <IUserRepository, InMemoryUserRepository>();

            // RealUserService depends on IUserRepository
            container.RegisterSingle <RealUserService>();

            container.Verify();

            // Act
            var item = DebuggerGeneralWarningsContainerAnalyzer.Analyze(container);

            // Assert
            Assert.AreEqual("1 possible lifestyle mismatch for 1 service.", item.Description);
        }
예제 #13
0
        public void Analyze_ContainerWithOneMismatch_ReturnsItemWithExpectedName()
        {
            // Arrange
            var container = new Container();

            container.Register <IUserRepository, InMemoryUserRepository>();

            // RealUserService depends on IUserRepository
            container.RegisterSingle <RealUserService>();

            container.Verify();

            // Act
            var item = DebuggerGeneralWarningsContainerAnalyzer.Analyze(container);

            // Assert
            Assert.AreEqual("Potential Lifestyle Mismatches", item.Name);
        }
예제 #14
0
        private DebuggerViewItem[] GetAnalysisResults()
        {
            var registrations = this.container.GetCurrentRegistrations();

            var rootRegistrations = this.container.GetRootRegistrations();

            return(new DebuggerViewItem[]
            {
                DebuggerGeneralWarningsContainerAnalyzer.Analyze(this.container),
                new DebuggerViewItem(
                    name: "Registrations",
                    description: "Count = " + registrations.Length,
                    value: registrations),
                new DebuggerViewItem(
                    name: "Root Registrations",
                    description: "Count = " + rootRegistrations.Length,
                    value: this.GroupProducers(rootRegistrations))
            });
        }
        public void Analyze_Uncached_ConfigurationWithViolation_ReturnsTheExpectedDebuggerViewItems()
        {
            // Arrange
            var container = new Container();

            container.AddRegistration(typeof(IFoo),
                                      Lifestyle.Singleton.CreateRegistrationInternal <FooBar>(container, preventTornLifestyles: false));
            container.AddRegistration(typeof(IBar),
                                      new ThreadScopedLifestyle().CreateRegistrationInternal <FooBar>(container, preventTornLifestyles: false));

            container.Verify(VerificationOption.VerifyOnly);

            // Act
            var results = DebuggerGeneralWarningsContainerAnalyzer.Analyze(container).Value as DebuggerViewItem[];

            // Assert
            Assert.AreEqual(typeof(IBar).Name, results[0].Name);
            Assert.AreEqual(typeof(IFoo).Name, results[1].Name);
        }
예제 #16
0
        public void Analyze_CollectionWithTypeWithTooManyDependencies_WarnsAboutThatViolation()
        {
            // Arrange
            Container container = CreateContainerWithRegistrations(Type.EmptyTypes);

            container.RegisterCollection <IPlugin>(new[] { typeof(PluginWith8Dependencies) });

            container.Verify();

            // Act
            var results = DebuggerGeneralWarningsContainerAnalyzer.Analyze(container).Value as DebuggerViewItem[];

            // Assert
            Assert.IsNotNull(results, "A warning should have been detected.");
            Assert.AreEqual(1, results.Length);
            Assert.AreEqual(
                typeof(PluginWith8Dependencies).Name + " has 8 dependencies which might indicate a SRP violation.",
                results[0].Description);
        }
        public void Analyze_ContainerWithOneMismatch_ReturnsItemWithExpectedName()
        {
            // Arrange
            var container = new Container();

            container.Options.SuppressLifestyleMismatchVerification = true;

            container.Register <IUserRepository, InMemoryUserRepository>();

            // RealUserService depends on IUserRepository
            container.Register <RealUserService>(Lifestyle.Singleton);

            container.Verify(VerificationOption.VerifyOnly);

            // Act
            var item = DebuggerGeneralWarningsContainerAnalyzer.Analyze(container);

            // Assert
            Assert.AreEqual("Lifestyle Mismatches", item.Name);
        }
예제 #18
0
        public void Analyze_ConfigurationWithCollectionADecoratorsWithTooManyDependencies_WarnsAboutThatDecorator()
        {
            // Arrange
            Container container = CreateContainerWithRegistrations(Type.EmptyTypes);

            // This decorator has too many dependencies
            container.RegisterDecorator(typeof(IPlugin), typeof(PluginDecoratorWith8Dependencies));

            // Non of these types have too many dependencies.
            container.RegisterCollection <IPlugin>(new[] { typeof(PluginImpl), typeof(SomePluginImpl) });

            container.Verify();

            // Act
            var results = DebuggerGeneralWarningsContainerAnalyzer.Analyze(container);

            // Assert
            // We expect two violations here, since the decorator is wrapping two different registrations.
            Assert.AreEqual("2 possible single responsibility violations.", results.Description);
        }
예제 #19
0
        public void Analyze_ConfigurationWithTwoViolationsOnSingleService_ReturnsOneViewItemForBothViolations()
        {
            // Arrange
            Container container = CreateContainerWithRegistration <IPlugin, PluginWith8Dependencies>();

            container.RegisterDecorator(typeof(IPlugin), typeof(PluginDecoratorWith8Dependencies));

            container.Verify();

            var ip = container.GetRegistration(typeof(IPlugin));

            // Act
            var items = DebuggerGeneralWarningsContainerAnalyzer.Analyze(container).Value as DebuggerViewItem[];

            // Assert
            Assert.AreEqual(1, items.Length);

            Assert.AreEqual(typeof(IPlugin).Name, items[0].Name);
            Assert.AreEqual("2 possible violations.", items[0].Description);
        }
예제 #20
0
        public void Analyze_OpenGenericRegistrationWithValidAmountOfDependencies_ReturnsNull()
        {
            // Arrange
            Container container = CreateContainerWithRegistrations();

            // Consumer class contains a IGenericPlugin<IDisposable> dependency
            container.Register <Consumer <IGenericPlugin <IDisposable> > >();

            // Register open generic type with 6 dependencies.
            container.Register(typeof(IGenericPlugin <>), typeof(GenericPluginWith6Dependencies <>));

            container.Verify();

            // Act
            var results = DebuggerGeneralWarningsContainerAnalyzer.Analyze(container);

            // Assert
            Assert.AreEqual("No warnings detected.", results.Description,
                            "The registration is considered to be valid, since both the type and decorator do not " +
                            "exceed the maximum number of dependencies. Message: {0}",
                            results == null ? null : results.Items().FirstOrDefault());
        }
예제 #21
0
        public void Analyze_ConfigurationWithTwoViolationsOnSingleService_ReturnsOneViewItemThatWrapsSecondViolation()
        {
            // Arrange
            Container container = CreateContainerWithRegistration <IPlugin, PluginWith8Dependencies>();

            container.RegisterDecorator(typeof(IPlugin), typeof(PluginDecoratorWith8Dependencies));

            container.Verify();

            // Act
            var results = DebuggerGeneralWarningsContainerAnalyzer.Analyze(container).Value as DebuggerViewItem[];

            var items = results.Single().Value as DebuggerViewItem[];

            var item = items.Single(i => i.Description.Contains(typeof(PluginDecoratorWith8Dependencies).Name));

            // Assert
            Assert.AreEqual("IPlugin", item.Name);
            Assert.AreEqual(typeof(PluginDecoratorWith8Dependencies).Name +
                            " has 8 dependencies which might indicate a SRP violation.",
                            item.Description);
        }