public void Discovering_with_Level3()
        {
            using (TestHelper.Monitor.OpenInfo("Without ObjectALevel4 class."))
            {
                var types = ThisAssembly.GetTypes()
                            .Where(t => t.IsClass)
                            .Where(t => (t.Namespace == "CK.StObj.Engine.Tests.SimpleObjects" ||
                                         t.Namespace == "CK.StObj.Engine.Tests.SimpleObjects.WithLevel3") &&
                                   t.Name != "ObjectALevel4");

                StObjCollector collector = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer());
                collector.RegisterTypes(types.ToList());

                var result = collector.GetResult( );
                Assert.That(result.HasFatalError, Is.False);
            }

            using (TestHelper.Monitor.OpenInfo("ObjectALevel4 class (specializes ObjectALevel3 and use IAbstractionBOnLevel2)."))
            {
                var types = ThisAssembly.GetTypes()
                            .Where(t => t.IsClass)
                            .Where(t => t.Namespace == "CK.StObj.Engine.Tests.SimpleObjects" ||
                                   t.Namespace == "CK.StObj.Engine.Tests.SimpleObjects.WithLevel3");

                StObjCollector collector = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer());
                collector.RegisterTypes(types.ToList());

                var result = collector.GetResult();
                Assert.That(result.HasFatalError, Is.False);
            }
        }
        public void Discovering_SimpleObjects()
        {
            var types = ThisAssembly.GetTypes()
                        .Where(t => t.IsClass)
                        .Where(t => t.Namespace == "CK.StObj.Engine.Tests.SimpleObjects");

            StObjCollector collector = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer());

            collector.RegisterTypes(types.ToList());

            var map = TestHelper.GetSuccessfulResult(collector).EngineMap;

            Debug.Assert(map != null, "No initialization error.");

            IStObjResult oa = map.StObjs.ToHead(typeof(ObjectA)) !;

            oa.Container !.ClassType.Should().Be(typeof(PackageForAB));
            oa.LeafSpecialization.ClassType.Should().Be(typeof(ObjectALevel3));

            IStObjResult oa1 = map.StObjs.ToHead(typeof(ObjectALevel1)) !;

            oa1.Generalization.Should().BeSameAs(oa);
            oa1.Container !.ClassType.Should().Be(typeof(PackageForABLevel1));

            IStObjResult oa2 = map.StObjs.ToHead(typeof(ObjectALevel2)) !;

            oa2.Generalization.Should().BeSameAs(oa1);
            oa2.Container !.ClassType.Should().Be(typeof(PackageForABLevel1), "Inherited.");

            IStObjResult oa3 = map.StObjs.ToHead(typeof(ObjectALevel3)) !;

            oa3.Generalization.Should().BeSameAs(oa2);
            oa3.Container !.ClassType.Should().Be(typeof(PackageForABLevel1), "Inherited.");
            oa.RootGeneralization.ClassType.Should().Be(typeof(ObjectA));
        }
        public void LayeredArchitecture()
        {
            var            valueResolver = new ValueResolver();
            StObjCollector collector     = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer(), valueResolver: valueResolver);

            collector.RegisterType(typeof(BasicPackage));
            collector.RegisterType(typeof(BasicActor));
            collector.RegisterType(typeof(BasicUser));
            collector.RegisterType(typeof(BasicGroup));
            collector.RegisterType(typeof(ZonePackage));
            collector.RegisterType(typeof(ZoneGroup));
            collector.RegisterType(typeof(SecurityZone));
            collector.RegisterType(typeof(AuthenticationPackage));
            collector.RegisterType(typeof(AuthenticationUser));
            collector.RegisterType(typeof(SqlDefaultDatabase));
            collector.DependencySorterHookInput  = items => items.Trace(TestHelper.Monitor);
            collector.DependencySorterHookOutput = sortedItems => sortedItems.Trace(TestHelper.Monitor);

            var r = TestHelper.GetSuccessfulResult(collector).EngineMap;

            Debug.Assert(r != null, "No initialization error.");

            WithAmbientTests.CheckChildren <BasicPackage>(r.StObjs, "BasicActor,BasicUser,BasicGroup");
            WithAmbientTests.CheckChildren <ZonePackage>(r.StObjs, "SecurityZone,ZoneGroup");
            WithAmbientTests.CheckChildren <SqlDefaultDatabase>(r.StObjs, "BasicPackage,BasicActor,BasicUser,BasicGroup,ZonePackage,SecurityZone,ZoneGroup,AuthenticationPackage,AuthenticationUser");
            var db = r.StObjs.Obtain <SqlDefaultDatabase>();

            Debug.Assert(db != null);
            db.ConnectionString.Should().Be("The connection String");
        }
        public void Attributes_can_NOT_YET_be_on_IRealObject_interface_members()
        {
            Assume.That(false, "This has to be implemented if needed, but this may not be really useful: a IRealObject is unambiguously mapped to its single implementation.");
            // => This could be done in CKTypeCollector.RegisterObjectClassInfo().

            OneCtorAttributeImpl.Constructed = false;

            var aspectProvidedServices = new SimpleServiceContainer();

            // Registers this AttributeTests (required by the OneCtorAttributeImpl constructor).
            aspectProvidedServices.Add(this);
            var c = new StObjCollector(TestHelper.Monitor, aspectProvidedServices);

            c.RegisterType(typeof(S7));

            var r = TestHelper.GetSuccessfulResult(c);

            Debug.Assert(r.EngineMap != null);

            r.EngineMap.AllTypesAttributesCache.Values.Select(attrs => attrs.Type).Should().BeEquivalentTo(
                new[] { typeof(S7), typeof(IRealObjectWithAttributeOnMember) });
            r.EngineMap.AllTypesAttributesCache.Values
            .SelectMany(attrs => attrs.GetAllCustomAttributes <IAttributeTypeSample>()).Should().HaveCount(1);

            OneCtorAttributeImpl.Constructed.Should().BeTrue();
        }
Example #5
0
 GenerateCodeResult IStObjEngineTestHelperCore.GenerateCode(StObjCollector c,
                                                            Func <StObjEngineConfiguration, StObjEngineConfiguration>?engineConfigurator,
                                                            bool generateSourceFile,
                                                            CompileOption compileOption)
 {
     return(DoGenerateCode(TestHelper.GetSuccessfulResult(c), engineConfigurator, generateSourceFile, compileOption));
 }
        public void Attributes_can_be_on_AutoService_interface_members()
        {
            OneCtorAttributeImpl.Constructed = false;

            var aspectProvidedServices = new SimpleServiceContainer();

            // Registers this AttributeTests (required by the OneCtorAttributeImpl constructor).
            aspectProvidedServices.Add(this);
            var c = new StObjCollector(TestHelper.Monitor, aspectProvidedServices);

            c.RegisterType(typeof(S6));

            var r = TestHelper.GetSuccessfulResult(c);

            Debug.Assert(r.EngineMap != null);

            r.EngineMap.AllTypesAttributesCache.Values
            .Select(attrs => attrs.Type)
            .Where(t => !typeof(PocoDirectory).IsAssignableFrom(t))
            .Should().BeEquivalentTo(new[] { typeof(S6), typeof(IServiceWithAttributeOnMember) });

            r.EngineMap.AllTypesAttributesCache.Values
            .SelectMany(attrs => attrs.GetAllCustomAttributes <IAttributeTypeSample>())
            .Should().HaveCount(1);

            OneCtorAttributeImpl.Constructed.Should().BeTrue();
        }
        public void closed_poco_and_CKTypeDefiner_and_CKTypeSuperDefiner_is_the_basis_of_the_Cris_ICommand(string mode)
        {
            var c = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer());

            if (mode == "AllBaseUserAndDocumentCloPocs")
            {
                c.RegisterTypes(BaseUserAndDocumentCloPocs);
            }
            else
            {
                c.RegisterType(typeof(IDocumentCloPoc));
                c.RegisterType(typeof(ICultureUserCloPoc));
            }
            var all = TestHelper.CreateAutomaticServices(c);

            try
            {
                var pocoSupportResult = all.CollectorResult.CKTypeResult.PocoSupport;
                Debug.Assert(pocoSupportResult != null);
                pocoSupportResult.Should().BeSameAs(all.CollectorResult.DynamicAssembly.GetPocoSupportResult());
                var services = all.Services;

                var dCloPoc = services.GetRequiredService <IPocoFactory <IDocumentCloPoc> >().Create();
                dCloPoc.Should().NotBeNull("Factories work.");

                var factoryCloPoc = services.GetService <IPocoFactory <IUserCloPoc> >();
                factoryCloPoc.Should().NotBeNull();

                services.GetService <IPocoFactory <ICloPoc> >().Should().BeNull("ICloPoc is a CKTypeDefiner.");
                services.GetService <IPocoFactory <ICloPocPart> >().Should().BeNull("ICloPocPart is a CKTypeSuperDefiner.");
                services.GetService <IPocoFactory <IAuthenticatedCloPocPart> >().Should().BeNull("Since ICloPocPart is a CKTypeSuperDefiner, a command part is NOT Poco.");

                pocoSupportResult.AllInterfaces.Should().HaveCount(3);
                pocoSupportResult.AllInterfaces.Values.Select(info => info.PocoInterface).Should().BeEquivalentTo(
                    new[] { typeof(IDocumentCloPoc), typeof(ICultureUserCloPoc), typeof(IUserCloPoc) });

                pocoSupportResult.OtherInterfaces.Keys.Should().BeEquivalentTo(
                    new[] { typeof(ICloPoc), typeof(ICloPocPart), typeof(IAuthenticatedCloPocPart), typeof(ICultureDependentCloPocPart) });

                pocoSupportResult.OtherInterfaces[typeof(ICloPoc)].Select(info => info.ClosureInterface).Should()
                .BeEquivalentTo(new[] { typeof(IDocumentCloPoc), typeof(ICultureUserCloPoc) });
                pocoSupportResult.OtherInterfaces[typeof(ICloPoc)].Select(info => info.PrimaryInterface).Should().BeEquivalentTo(
                    new[] { typeof(IDocumentCloPoc), typeof(IUserCloPoc) });

                pocoSupportResult.OtherInterfaces[typeof(ICloPocPart)].Should().BeEquivalentTo(
                    pocoSupportResult.OtherInterfaces[typeof(ICloPoc)], "Our 2 commands have parts.");
                pocoSupportResult.OtherInterfaces[typeof(IAuthenticatedCloPocPart)].Should().BeEquivalentTo(
                    pocoSupportResult.OtherInterfaces[typeof(ICloPoc)], "Our 2 commands have IAuthenticatedCloPocPart part.");
                pocoSupportResult.OtherInterfaces[typeof(ICultureDependentCloPocPart)].Select(info => info.ClosureInterface).Should().BeEquivalentTo(
                    new[] { typeof(ICultureUserCloPoc) });

                var factoryCultCloPoc = services.GetService <IPocoFactory <ICultureUserCloPoc> >();
                factoryCultCloPoc.Should().BeSameAs(factoryCloPoc);
            }
            finally
            {
                all.Services.Dispose();
            }
        }
Example #8
0
        static StObjCollectorResult DoGetSuccessfulResult(StObjCollector c)
        {
            c.RegisteringFatalOrErrorCount.Should().Be(0, "There must be no registration error (CKTypeCollector must be successful).");
            StObjCollectorResult?r = c.GetResult();

            r.HasFatalError.Should().Be(false, "There must be no error.");
            return(r);
        }
        public void not_closed_poco_commmand_are_detected()
        {
            var c = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer());

            c.RegisterType(typeof(IOther1UserCloPoc));
            c.RegisterType(typeof(IOther2UserCloPoc));
            TestHelper.GetFailedResult(c);
        }
 public void InjectSingleton_must_not_be_scoped_service()
 {
     {
         StObjCollector collector = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer());
         collector.RegisterType(typeof(InvalidRealObjectProperty));
         collector.GetResult().HasFatalError.Should().BeTrue();
     }
 }
 public void SetterMustExistOnTopDefiner()
 {
     {
         StObjCollector collector = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer());
         collector.RegisterType(typeof(CMissingSetterOnTopDefiner));
         collector.RegisterType(typeof(CA2));
         Assert.That(collector.RegisteringFatalOrErrorCount, Is.EqualTo(1));
     }
 }
 public void Missing_reference()
 {
     using (TestHelper.Monitor.OpenInfo("ObjectXNeedsY without ObjectYNeedsX."))
     {
         StObjCollector collector = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer());
         collector.RegisterType(typeof(ObjectXNeedsY));
         TestHelper.GetFailedResult(collector);
     }
 }
        public void abstract_non_auto_implementable_leaf_are_silently_ignored()
        {
            StObjCollector collector = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer());

            collector.RegisterType(typeof(A3));
            var r = TestHelper.GetSuccessfulResult(collector);

            Debug.Assert(r.EngineMap != null, "No initialization error.");
            r.EngineMap.StObjs.Obtain <A>().Should().NotBeNull().And.BeAssignableTo <A>().And.NotBeAssignableTo <A3>();
        }
        public void abstract_auto_impl_is_supported_on_non_IRealObject_base_class()
        {
            StObjCollector collector = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer());

            collector.RegisterType(typeof(A2));
            var r = TestHelper.GetSuccessfulResult(collector);

            Debug.Assert(r.EngineMap != null, "No initialization error.");
            r.EngineMap.StObjs.Obtain <A>().Should().NotBeNull().And.BeAssignableTo <A2>();
        }
        public void a_RealObject_that_references_an_auto_service_from_an_InjectObject_is_an_error()
        {
            var            types     = new[] { typeof(AmbientInject) };
            StObjCollector collector = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer());

            collector.RegisterTypes(types.ToList());
            var result = collector.GetResult();

            Assert.That(result.HasFatalError, Is.True);
        }
        public void ObjectXNeedsY_and_ObjectYNeedsX_Cycle()
        {
            using (TestHelper.Monitor.OpenInfo("ObjectXNeedsY and ObjectYNeedsX."))
            {
                StObjCollector collector = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer());
                collector.RegisterType(typeof(ObjectXNeedsY));
                collector.RegisterType(typeof(ObjectYNeedsX));

                TestHelper.GetFailedResult(collector);
            }
        }
        public void PropagationFromAmbientProperty()
        {
            StObjCollector collector = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer(), configurator: new ConfiguratorOneIntValueSetTo42());

            collector.RegisterType(typeof(SimpleObjectAmbient));
            collector.RegisterType(typeof(SimpleObjectInsideAmbient));
            var map = TestHelper.GetSuccessfulResult(collector).EngineMap;

            Debug.Assert(map != null, "No initialization error.");
            Assert.That(map.StObjs.Obtain <SimpleObjectInsideAmbient>() !.OneIntValue, Is.EqualTo(42), "Of course, ambient properties propagate their values.");
        }
            public void DoTest()
            {
                IReadOnlyList <ActivityMonitorSimpleCollector.Entry>?logs = null;

                using (TestHelper.Monitor.CollectEntries(entries => logs = entries, LogLevelFilter.Trace, 1000))
                {
                    StObjCollector collector = TestHelper.CreateStObjCollector(typeof(S1), typeof(S2));
                    TestHelper.CompileAndLoadStObjMap(collector).Map.Should().NotBeNull();
                }
                logs.Should().Contain(e => e.Text == "AutoImpl2: I'm great!.")
                .And.Contain(e => e.Text == "AutoImpl in another pass: I'm great!.");
            }
            public static void DoTest()
            {
                IReadOnlyList <ActivityMonitorSimpleCollector.Entry>?logs = null;

                using (TestHelper.Monitor.CollectEntries(entries => logs = entries, LogLevelFilter.Trace, 1000))
                {
                    StObjCollector collector = TestHelper.CreateStObjCollector(typeof(S1), typeof(S2));
                    TestHelper.CompileAndLoadStObjMap(collector).Map.Should().NotBeNull();
                }
                logs.Should().Contain(e => e.Text == "ActualImpl1: I'm great!, I'm SOOOO great!.");
                logs.Should().NotContain(e => e.Text.Contains("Because nobody added me", StringComparison.Ordinal));
            }
        public void PropagationFromDirectPropertyDoesNotWork()
        {
            StObjCollector collector = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer(), configurator: new ConfiguratorOneIntValueSetTo42());

            collector.RegisterType(typeof(SimpleObjectDirect));
            collector.RegisterType(typeof(SimpleObjectInsideDirect));
            var map = TestHelper.GetSuccessfulResult(collector).EngineMap;

            Debug.Assert(map != null, "No initialization error.");
            Assert.That(map.StObjs.Obtain <SimpleObjectInsideDirect>() !.OneIntValue, Is.EqualTo(0), "A direct property (not an ambient property) CAN NOT be a source for ambient properties.");
            Assert.That(map.StObjs.Obtain <SimpleObjectDirect>() !.OneIntValue, Is.EqualTo(42), "...But it can be set by any IStObjStructuralConfigurator participant.");
        }
Example #21
0
        StObjCollectorResult?IStObjEngineTestHelperCore.GetFailedResult(StObjCollector c)
        {
            if (c.RegisteringFatalOrErrorCount != 0)
            {
                TestHelper.Monitor.Error($"GetFailedResult: {c.RegisteringFatalOrErrorCount} fatal or error during StObjCollector registration. (Everything is fine since an error was expected.)");
                return(null);
            }
            var r = c.GetResult();

            r.HasFatalError.Should().Be(true, "GetFailedResult: StObjCollector.GetResult() must have failed with at least one fatal error.");
            return(r);
        }
        public void abstract_auto_implementable_leaf_but_using_PreventAutoImplementationAttribute_are_silently_ignored()
        {
            StObjCollector collector = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer());

            collector.RegisterType(typeof(A4));

            StObjCollectorResult result = TestHelper.GetSuccessfulResult(collector);

            Debug.Assert(result.EngineMap != null, "No initialization error.");

            result.EngineMap.StObjs.Obtain <A>().Should().NotBeNull().And.BeAssignableTo <A>().And.NotBeAssignableTo <A4>();
        }
Example #23
0
 public void OneObject()
 {
     {
         StObjCollector collector = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer());
         collector.RegisterType(typeof(SimpleContainer));
         var result = collector.GetResult().EngineMap !.StObjs;
         result.OrderedStObjs
         .Where(o => o.FinalImplementation.Implementation is not PocoDirectory)
         .First()
         .GetStObjProperty("OneIntValue").Should().Be(3712);
     }
 }
        public void PrivateSetterWorks()
        {
            {
                StObjCollector collector = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer());
                collector.RegisterType(typeof(CPrivateSetter));
                collector.RegisterType(typeof(CA2));
                var map = TestHelper.GetSuccessfulResult(collector).EngineMap;
                Debug.Assert(map != null, "No initialization error.");

                var c = map.StObjs.Obtain <CPrivateSetter>() !;
                Assert.That(c.A, Is.InstanceOf <CA2>());
            }
        }
            public void DoTest()
            {
                var extraServices = new SimpleServiceContainer();

                extraServices.Add <Func <string> >(() => "Hello World!");

                StObjCollector collector = new StObjCollector(TestHelper.Monitor, extraServices);

                collector.RegisterType(typeof(JustForTheAttribute));
                var r = collector.GetResult();

                Assert.That(r.HasFatalError, Is.False);
            }
Example #26
0
        static CompileAndLoadResult DoCompileAndLoadStObjMap(StObjCollector c,
                                                             Func <StObjEngineConfiguration, StObjEngineConfiguration>?engineConfigurator,
                                                             bool useEmbeddedStObjMapIfPossible)
        {
            // If the embeddedStObjMap must be used, we update the G0.cs file, but if the StObjMap must be loaded from the assembly
            // we avoid updating G0.cs.
            GenerateCodeResult r = DoGenerateCode(TestHelper.GetSuccessfulResult(c), engineConfigurator, useEmbeddedStObjMapIfPossible, CompileOption.Compile);

            r.Success.Should().BeTrue("CodeGeneration should work.");
            var map = r.EngineResult.Groups[0].LoadStObjMap(useEmbeddedStObjMapIfPossible);

            return(new CompileAndLoadResult(r, map !));
        }
        public void StObj_must_have_only_one_specialization_chain()
        {
            var types = ThisAssembly.GetTypes()
                        .Where(t => t.IsClass)
                        .Where(t => t.Namespace == "CK.StObj.Engine.Tests.SimpleObjects");

            var collector = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer());

            collector.RegisterTypes(types.ToList());
            collector.RegisterType(typeof(ObjectALevel1Conflict));
            var result = collector.GetResult();

            result.HasFatalError.Should().BeTrue();
        }
Example #28
0
        AutomaticServicesResult IStObjEngineTestHelperCore.CreateAutomaticServices(StObjCollector c,
                                                                                   Func <StObjEngineConfiguration, StObjEngineConfiguration>?engineConfigurator,
                                                                                   SimpleServiceContainer?startupServices,
                                                                                   Action <StObjContextRoot.ServiceRegister>?configureServices)
        {
            var loadResult = DoCompileAndLoadStObjMap(c, engineConfigurator, true);

            var reg = new StObjContextRoot.ServiceRegister(TestHelper.Monitor, new ServiceCollection(), startupServices);

            reg.AddStObjMap(loadResult.Map).Should().BeTrue("Service configuration succeed.");
            configureServices?.Invoke(reg);

            return(new AutomaticServicesResult(loadResult, reg, reg.Services.BuildServiceProvider()));
        }
        static StObjCollectorResult BuildPocoSample(params Type[] extra)
        {
            var types = typeof(PocoTests).Assembly.GetTypes()
                        .Where(t => t.Namespace == "CK.StObj.Engine.Tests.Poco.Sample")
                        .Concat(extra);

            StObjCollector collector = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer());

            collector.RegisterTypes(types.ToList());

            var result = collector.GetResult();

            Assert.That(result.HasFatalError, Is.False);
            return(result);
        }
            public void DoTest()
            {
                StObjCollector collector = new StObjCollector(TestHelper.Monitor, new SimpleServiceContainer(), configurator: new StObjPropertyConfigurator());

                collector.RegisterType(typeof(BSpec));
                collector.RegisterType(typeof(ASpec));
                collector.DependencySorterHookInput  = items => items.Trace(TestHelper.Monitor);
                collector.DependencySorterHookOutput = sortedItems => sortedItems.Trace(TestHelper.Monitor);



                var(r, map) = TestHelper.CompileAndLoadStObjMap(collector);

                // Check collector result.
                {
                    Assert.That(r.HasFatalError, Is.False);
                    Debug.Assert(r.EngineMap != null, "Since HasFatalError is false.");
                    IStObjObjectEngineMap stObjs = r.EngineMap.StObjs;

                    Assert.That(stObjs.Obtain <B>() !.TheA, Is.SameAs(stObjs.Obtain <A>()).And.SameAs(stObjs.Obtain <ASpec>()));
                    Assert.That(stObjs.Obtain <ASpec>() !.TheB, Is.SameAs(stObjs.Obtain <B>()));
                    Assert.That(stObjs.ToHead(typeof(A)) !.GetStObjProperty("StObjPower"), Is.EqualTo("This is the A property."));
                    Assert.That(stObjs.ToHead(typeof(ASpec)) !.GetStObjProperty("StObjPower"), Is.EqualTo("ASpec level property."));

                    ASpec theA = (ASpec)stObjs.Obtain <A>() !;
                    Assert.That(theA.StObjPower, Is.EqualTo("ASpec level property."));
                    Assert.That(typeof(A).GetProperty("StObjPower")?.GetValue(theA, null), Is.EqualTo("This is the A property."));
                    Assert.That(theA.StObjInitializeOnACalled, Is.False, "StObjInitialize is NOT called on setup instances.");
                }

                // Check generated StObjMap.
                {
                    Debug.Assert(map != null);
                    Assert.That(map.StObjs.Obtain <B>() !.TheA, Is.SameAs(map.StObjs.Obtain <A>()).And.SameAs(map.StObjs.Obtain <ASpec>()));
                    Assert.That(map.StObjs.Obtain <ASpec>() !.TheB, Is.SameAs(map.StObjs.Obtain <B>()));

                    ASpec theA = (ASpec)map.StObjs.Obtain <A>() !;
                    theA.Should().NotBeNull();
                    Assert.That(theA.StObjPower, Is.EqualTo("ASpec level property."));
                    Assert.That(typeof(A).GetProperty("StObjPower")?.GetValue(theA, null), Is.EqualTo("This is the A property."));

                    Assert.That(theA.TheB, Is.SameAs(map.StObjs.Obtain <B>()));
                    Assert.That(map.StObjs.Obtain <B>() !.TheInjectedA, Is.SameAs(theA));

                    Assert.That(theA.StObjInitializeOnACalled, Is.True);
                    Assert.That(theA.StObjInitializeOnASpecCalled, Is.True);
                }
            }