public void Remove()
        {
            int index       = -1;
            var instanceIds = new List <PartInstanceId>
            {
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
            };
            var storage = new Mock <IStoreInstances>();
            {
                storage.Setup(
                    s => s.Construct(
                        It.IsAny <GroupPartDefinition>(),
                        It.IsAny <IEnumerable <Tuple <ImportRegistrationId, PartInstanceId, ExportRegistrationId> > >()))
                .Returns(
                    () =>
                {
                    index++;
                    return(instanceIds[index]);
                });

                storage.Setup(s => s.Release(It.IsAny <PartInstanceId>()))
                .Returns <PartInstanceId>(
                    i =>
                {
                    return(new List <InstanceUpdate>
                    {
                        new InstanceUpdate
                        {
                            Instance = i,
                            Change = InstanceChange.Removed,
                        }
                    });
                })
                .Verifiable();
            }

            var layer = CompositionLayer.CreateInstanceWithoutTimeline(storage.Object);

            var groupId    = new GroupCompositionId();
            var definition = CreateExportingDefinition();

            layer.Add(groupId, definition);

            Assert.AreEqual(1, layer.Groups().Count());
            Assert.AreSame(groupId, layer.Groups().First());
            Assert.AreSame(definition, layer.Group(groupId));

            layer.Remove(groupId);
            Assert.AreEqual(0, layer.Groups().Count());
            storage.Verify(s => s.Release(It.IsAny <PartInstanceId>()), Times.Exactly(5));
        }
        public void DisconnectFromAll()
        {
            int index       = -1;
            var instanceIds = new List <PartInstanceId>
            {
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
            };
            var storage = new Mock <IStoreInstances>();
            {
                storage.Setup(
                    s => s.Construct(
                        It.IsAny <GroupPartDefinition>(),
                        It.IsAny <IEnumerable <Tuple <ImportRegistrationId, PartInstanceId, ExportRegistrationId> > >()))
                .Returns(
                    () =>
                {
                    index++;
                    return(instanceIds[index]);
                });

                storage.Setup(s => s.Release(It.IsAny <PartInstanceId>()))
                .Returns <PartInstanceId>(
                    i =>
                {
                    return(new List <InstanceUpdate>
                    {
                        new InstanceUpdate
                        {
                            Instance = i,
                            Change = InstanceChange.Removed,
                        }
                    });
                })
                .Verifiable();
            }

            var layer = CompositionLayer.CreateInstanceWithoutTimeline(storage.Object);

            var firstId         = new GroupCompositionId();
            var firstDefinition = CreateExportingDefinition();

            layer.Add(firstId, firstDefinition);

            var secondId         = new GroupCompositionId();
            var secondDefinition = CreateImportingDefinition();

            layer.Add(secondId, secondDefinition);

            Assert.IsFalse(layer.SatisfiedImports(secondId).Any());
            Assert.That(layer.UnsatisfiedImports(secondId), Is.EquivalentTo(secondDefinition.GroupImports));

            layer.Connect(new GroupConnection(
                              secondId,
                              firstId,
                              secondDefinition.GroupImports.First(),
                              new List <PartImportToPartExportMap>
            {
                new PartImportToPartExportMap(
                    secondDefinition.GroupImports.First().ImportsToMatch.ElementAt(0),
                    new List <ExportRegistrationId>
                {
                    firstDefinition.GroupExport.ProvidedExports.ElementAt(0)
                }),
                new PartImportToPartExportMap(
                    secondDefinition.GroupImports.First().ImportsToMatch.ElementAt(1),
                    new List <ExportRegistrationId>
                {
                    firstDefinition.GroupExport.ProvidedExports.ElementAt(1),
                    firstDefinition.GroupExport.ProvidedExports.ElementAt(2),
                }),
            }));

            Assert.IsFalse(layer.UnsatisfiedImports(secondId).Any());
            Assert.That(
                layer.SatisfiedImports(secondId),
                Is.EquivalentTo(
                    new List <Tuple <GroupImportDefinition, GroupCompositionId> >
            {
                new Tuple <GroupImportDefinition, GroupCompositionId>(secondDefinition.GroupImports.First(), firstId)
            }));

            layer.Disconnect(firstId);

            Assert.IsFalse(layer.SatisfiedImports(secondId).Any());
            Assert.That(layer.UnsatisfiedImports(secondId), Is.EquivalentTo(secondDefinition.GroupImports));
            storage.Verify(s => s.Release(It.IsAny <PartInstanceId>()), Times.Exactly(1));
        }
        public void Connect()
        {
            int index       = -1;
            var instanceIds = new List <PartInstanceId>
            {
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
            };
            var storage = new Mock <IStoreInstances>();
            {
                storage.Setup(
                    s => s.Construct(
                        It.IsAny <GroupPartDefinition>(),
                        It.IsAny <IEnumerable <Tuple <ImportRegistrationId, PartInstanceId, ExportRegistrationId> > >()))
                .Callback <GroupPartDefinition, IEnumerable <Tuple <ImportRegistrationId, PartInstanceId, ExportRegistrationId> > >(
                    (d, i) =>
                {
                    if (d.Identity.Equals(TypeIdentity.CreateDefinition(typeof(List <string>))))
                    {
                        Assert.AreEqual(0, i.Count());
                    }

                    if (d.Identity.Equals(TypeIdentity.CreateDefinition(typeof(List <double>))))
                    {
                        Assert.AreEqual(2, i.Count());
                        Assert.AreEqual(instanceIds[1], i.ElementAt(0).Item2);
                        Assert.AreEqual(instanceIds[2], i.ElementAt(1).Item2);
                    }
                })
                .Returns <GroupPartDefinition, IEnumerable <Tuple <ImportRegistrationId, PartInstanceId, ExportRegistrationId> > >(
                    (d, i) =>
                {
                    index++;
                    return(instanceIds[index]);
                })
                .Verifiable();

                storage.Setup(
                    s => s.UpdateIfRequired(
                        It.IsAny <PartInstanceId>(),
                        It.IsAny <IEnumerable <Tuple <ImportRegistrationId, PartInstanceId, ExportRegistrationId> > >()))
                .Callback <PartInstanceId, IEnumerable <Tuple <ImportRegistrationId, PartInstanceId, ExportRegistrationId> > >(
                    (i, l) =>
                {
                    if (i.Equals(instanceIds[5]))
                    {
                        Assert.AreEqual(1, l.Count());
                        Assert.AreEqual(instanceIds[0], l.ElementAt(0).Item2);
                    }
                })
                .Returns <PartInstanceId, IEnumerable <Tuple <ImportRegistrationId, PartInstanceId, ExportRegistrationId> > >(
                    (i, l) =>
                {
                    return(new List <InstanceUpdate>
                    {
                        new InstanceUpdate
                        {
                            Instance = i,
                            Change = InstanceChange.Updated,
                        }
                    });
                })
                .Verifiable();
            }

            var layer = CompositionLayer.CreateInstanceWithoutTimeline(storage.Object);

            var firstId         = new GroupCompositionId();
            var firstDefinition = CreateExportingDefinition();

            layer.Add(firstId, firstDefinition);

            var secondId         = new GroupCompositionId();
            var secondDefinition = CreateImportingDefinition();

            layer.Add(secondId, secondDefinition);

            Assert.IsFalse(layer.SatisfiedImports(secondId).Any());
            Assert.That(layer.UnsatisfiedImports(secondId), Is.EquivalentTo(secondDefinition.GroupImports));

            layer.Connect(new GroupConnection(
                              secondId,
                              firstId,
                              secondDefinition.GroupImports.First(),
                              new List <PartImportToPartExportMap>
            {
                new PartImportToPartExportMap(
                    secondDefinition.GroupImports.First().ImportsToMatch.ElementAt(0),
                    new List <ExportRegistrationId>
                {
                    firstDefinition.GroupExport.ProvidedExports.ElementAt(0)
                }),
                new PartImportToPartExportMap(
                    secondDefinition.GroupImports.First().ImportsToMatch.ElementAt(1),
                    new List <ExportRegistrationId>
                {
                    firstDefinition.GroupExport.ProvidedExports.ElementAt(1),
                    firstDefinition.GroupExport.ProvidedExports.ElementAt(2),
                }),
            }));

            Assert.IsFalse(layer.UnsatisfiedImports(secondId).Any());
            Assert.That(
                layer.SatisfiedImports(secondId),
                Is.EquivalentTo(
                    new List <Tuple <GroupImportDefinition, GroupCompositionId> >
            {
                new Tuple <GroupImportDefinition, GroupCompositionId>(secondDefinition.GroupImports.First(), firstId)
            }));

            storage.Verify(
                s => s.Construct(
                    It.IsAny <GroupPartDefinition>(),
                    It.IsAny <IEnumerable <Tuple <ImportRegistrationId, PartInstanceId, ExportRegistrationId> > >()),
                Times.Exactly(7));
        }
        public void AddMultipleInstanceWithSameDefinition()
        {
            var firstDefinition = CreateExportingDefinition();

            int index       = -1;
            var instanceIds = new List <PartInstanceId>
            {
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
                new PartInstanceId(),
            };
            var storage = new Mock <IStoreInstances>();
            {
                storage.Setup(
                    s => s.Construct(
                        It.IsAny <GroupPartDefinition>(),
                        It.IsAny <IEnumerable <Tuple <ImportRegistrationId, PartInstanceId, ExportRegistrationId> > >()))
                .Callback <GroupPartDefinition, IEnumerable <Tuple <ImportRegistrationId, PartInstanceId, ExportRegistrationId> > >(
                    (d, i) =>
                {
                    if (d.Identity.Equals(TypeIdentity.CreateDefinition(typeof(int))))
                    {
                        Assert.IsFalse(i.Any());
                        return;
                    }

                    if (d.Identity.Equals(TypeIdentity.CreateDefinition(typeof(string))))
                    {
                        Assert.IsFalse(i.Any());
                        return;
                    }

                    if (d.Identity.Equals(TypeIdentity.CreateDefinition(typeof(Version))))
                    {
                        Assert.IsFalse(i.Any());
                        return;
                    }

                    if (d.Identity.Equals(TypeIdentity.CreateDefinition(typeof(DateTime))))
                    {
                        Assert.IsFalse(i.Any());
                        return;
                    }

                    if (d.Identity.Equals(TypeIdentity.CreateDefinition(typeof(List <int>))))
                    {
                        Assert.AreEqual(1, i.Count());
                        Assert.AreEqual(instanceIds[index], i.First().Item2);
                        return;
                    }

                    Assert.Fail();
                })
                .Returns <GroupPartDefinition, IEnumerable <Tuple <ImportRegistrationId, PartInstanceId, ExportRegistrationId> > >(
                    (d, i) =>
                {
                    index++;
                    return(instanceIds[index]);
                })
                .Verifiable();
            }

            var layer = CompositionLayer.CreateInstanceWithoutTimeline(storage.Object);

            var firstId = new GroupCompositionId();

            layer.Add(firstId, firstDefinition);

            var secondId         = new GroupCompositionId();
            var secondDefinition = CreateExportingDefinition();

            layer.Add(secondId, secondDefinition);

            Assert.AreEqual(2, layer.Groups().Count());
            Assert.AreSame(firstDefinition, layer.Group(firstId));
            Assert.AreSame(firstDefinition, layer.Group(secondId));

            storage.Verify(
                s => s.Construct(
                    It.IsAny <GroupPartDefinition>(),
                    It.IsAny <IEnumerable <Tuple <ImportRegistrationId, PartInstanceId, ExportRegistrationId> > >()),
                Times.Exactly(10));
        }