/// <summary>
        /// Enables Managed Extensibility Framework two-way integration.
        /// </summary>
        /// <param name="unityContainer">Target container.</param>
        /// <returns>
        /// <see cref="CompositionIntegration"/> instance.
        /// </returns>
        public static CompositionIntegration EnableCompositionIntegration(
            this IUnityContainer unityContainer)
        {
            lock (unityContainer)
            {
                var extension = unityContainer.Configure<CompositionIntegration>();
                if (extension == null)
                {
                    var adapter = new UnityContainerAdapter(unityContainer);
                    var containerExportProvider = new ContainerExportProvider(adapter);
                    var parentExtension = (CompositionIntegration) null;

                    if (unityContainer.Parent != null)
                    {
                        parentExtension = unityContainer.Parent.Configure<CompositionIntegration>();
                    }

                    if (parentExtension != null)
                    {
                        // Get the parent ContainerExportProvider
                        var parentContainerExportProvider = (ContainerExportProvider)parentExtension.Providers.Where(
                            ep => typeof(ContainerExportProvider).IsAssignableFrom(ep.GetType())).First();

                        // Collect all the exports provided by the parent container and add
                        // them to the child export provider
                        foreach (var definition in parentContainerExportProvider.FactoryExportProvider.ReadOnlyDefinitions)
                        {
                            containerExportProvider.FactoryExportProvider.Register(
                                definition.ContractType,
                                definition.RegistrationName);
                        }

                        // Grab all the parent export providers except the container ones
                        var parentExporters = new List<ExportProvider>(
                            parentExtension.Providers.Where(
                                ep => !typeof (ContainerExportProvider).IsAssignableFrom(ep.GetType())))
                                                  { containerExportProvider };

                        var catalog = new AggregateCatalog(parentExtension.Catalogs);

                        extension = new CompositionIntegration(true, parentExporters.ToArray());
                        extension.Catalogs.Add(catalog);
                    }
                    else
                    {
                        extension = new CompositionIntegration(true, containerExportProvider);
                    }

                    unityContainer.AddExtension(extension);
                }

                return extension;
            }
        }
        public void ExportProviderResolvesServiceRegisteredByTypeTest()
        {
            // Setup
            var builder = new ContainerBuilder();
            builder.RegisterType<AutofacOnlyComponent1>().As<IAutofacOnlyComponent>();
            var autofacContainer = builder.Build();
            var adapter = new AutofacContainerAdapter(autofacContainer);
            var provider = new ContainerExportProvider(adapter);

            var component = provider.GetExportedValue<IAutofacOnlyComponent>();
            Assert.That(component, Is.Not.Null);
            Assert.That(component.GetType(), Is.EqualTo(typeof(AutofacOnlyComponent1)));
        }
        public void ExportProviderResolvesServiceRegisteredByTypeAndRegistrationNameTest()
        {
            // Setup
            var unityContainer = new UnityContainer();
            var adapter = new UnityContainerAdapter(unityContainer);
            var provider = new ContainerExportProvider(adapter);

            // Registration
            unityContainer.RegisterType<IUnityOnlyComponent, UnityOnlyComponent2>("unityComponent2");

            var component = provider.GetExportedValue<IUnityOnlyComponent>("unityComponent2");
            Assert.That(component, Is.Not.Null);
            Assert.That(component.GetType(), Is.EqualTo(typeof(UnityOnlyComponent2)));
        }
        public void ExportProviderResolvesServicesRegisteredByTypeTest()
        {
            // Setup
            var builder = new ContainerBuilder();
            builder.RegisterType<AutofacOnlyComponent1>().As<IAutofacOnlyComponent>();
            builder.RegisterType<AutofacOnlyComponent2>().Named<IAutofacOnlyComponent>("b");
            var autofacContainer = builder.Build();
            var adapter = new AutofacContainerAdapter(autofacContainer);
            var provider = new ContainerExportProvider(adapter);

            var components = provider.GetExports<IAutofacOnlyComponent>();
            Assert.That(components, Is.Not.Null);
            Assert.That(components.Count(), Is.EqualTo(2));

            Assert.That(components.Select(t => t.Value).OfType<AutofacOnlyComponent1>().Count(), Is.EqualTo(1));
            Assert.That(components.Select(t => t.Value).OfType<AutofacOnlyComponent2>().Count(), Is.EqualTo(1));
        }
        public void ExportProviderResolvesServicesRegisteredByTypeTest()
        {
            // Setup
            var unityContainer = new UnityContainer();
            var adapter = new UnityContainerAdapter(unityContainer);
            var provider = new ContainerExportProvider(adapter);

            // Registration
            unityContainer.RegisterType<IUnityOnlyComponent, UnityOnlyComponent1>();
            unityContainer.RegisterType<IUnityOnlyComponent, UnityOnlyComponent2>("b");

            var components = provider.GetExports<IUnityOnlyComponent>();
            Assert.That(components, Is.Not.Null);
            Assert.That(components.Count(), Is.EqualTo(2));

            Assert.That(components.Select(t => t.Value).OfType<UnityOnlyComponent1>().Count(), Is.EqualTo(1));
            Assert.That(components.Select(t => t.Value).OfType<UnityOnlyComponent2>().Count(), Is.EqualTo(1));
        }
        public void MefCanResolveLazyTypeRegisteredInUnityTest()
        {
            // Setup
            var unityContainer = new UnityContainer();
            var adapter = new UnityContainerAdapter(unityContainer);
            var provider = new ContainerExportProvider(adapter);
            var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            var container = new CompositionContainer(assemblyCatalog, provider);

            UnityOnlyComponent1.InstanceCount = 0;
            unityContainer.RegisterType<IUnityOnlyComponent, UnityOnlyComponent1>();

            var lazyUnityComponent = container.GetExport<IUnityOnlyComponent>();
            Assert.That(lazyUnityComponent, Is.Not.Null);
            Assert.That(UnityOnlyComponent1.InstanceCount, Is.EqualTo(0));

            Assert.That(lazyUnityComponent.Value, Is.Not.Null);
            Assert.That(lazyUnityComponent.Value.GetType(), Is.EqualTo(typeof(UnityOnlyComponent1)));
            Assert.That(UnityOnlyComponent1.InstanceCount, Is.EqualTo(1));
        }
        public void MefCanResolveLazyTypeRegisteredInAutofacTest()
        {
            // Setup
            var builder = new ContainerBuilder();
            builder.RegisterType<AutofacOnlyComponent1>().As<IAutofacOnlyComponent>();
            var autofacContainer = builder.Build();
            var adapter = new AutofacContainerAdapter(autofacContainer);
            var provider = new ContainerExportProvider(adapter);
            var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            var container = new CompositionContainer(assemblyCatalog, provider);

            AutofacOnlyComponent1.InstanceCount = 0;

            var lazyAutofacComponent = container.GetExport<IAutofacOnlyComponent>();
            Assert.That(lazyAutofacComponent, Is.Not.Null);
            Assert.That(AutofacOnlyComponent1.InstanceCount, Is.EqualTo(0));

            Assert.That(lazyAutofacComponent.Value, Is.Not.Null);
            Assert.That(lazyAutofacComponent.Value.GetType(), Is.EqualTo(typeof(AutofacOnlyComponent1)));
            Assert.That(AutofacOnlyComponent1.InstanceCount, Is.EqualTo(1));
        }
        public void ComposeWithTwoContainerExportProvidersTest()
        {
            var builder1 = new ContainerBuilder();
            var a = new A();
            builder1.RegisterInstance(a);
            var autofacContainer1 = builder1.Build();
            var exportProvider1 = new ContainerExportProvider(new AutofacContainerAdapter(autofacContainer1));

            var builder2 = new ContainerBuilder();
            var b = new B();
            builder2.RegisterInstance(b);
            var autofacContainer2 = builder2.Build();
            var exportProvider2 = new ContainerExportProvider(new AutofacContainerAdapter(autofacContainer2));

            var catalog = new TypeCatalog(typeof(C));
            var compositionContainer = new CompositionContainer(catalog, exportProvider1, exportProvider2);
            var instance = compositionContainer.GetExport<C>();
            Assert.IsNotNull(instance.Value);
            Assert.AreEqual(a, instance.Value.ThingA, "Instance of A is the same as that registered with the DI container.");
            Assert.AreEqual(b, instance.Value.ThingB, "Instance of B is the same as that registered with the DI container.");
        }
        public void MefCanResolveTypesRegisteredInAutofacAfterTrackingExtensionIsAddedTest()
        {
            // Setup
            var builder = new ContainerBuilder();
            builder.RegisterType<AutofacOnlyComponent2>().Named<IAutofacOnlyComponent>("autofacComponent2");
            var autofacContainer = builder.Build();

            // Further setup
            var adapter = new AutofacContainerAdapter(autofacContainer);
            var provider = new ContainerExportProvider(adapter);
            var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            var container = new CompositionContainer(assemblyCatalog, provider);

            var component = container.GetExportedValue<IAutofacOnlyComponent>("autofacComponent2");
            Assert.That(component, Is.Not.Null);
            Assert.That(component.GetType(), Is.EqualTo(typeof(AutofacOnlyComponent2)));
        }
        public void MefCanResolveTypesRegisteredInUnityAfterTrackingExtensionIsAddedTest()
        {
            // Setup
            var unityContainer = new UnityContainer();

            // Enable tracking
            TypeRegistrationTrackerExtension.RegisterIfMissing(unityContainer);

            // Registration
            unityContainer.RegisterType<IUnityOnlyComponent, UnityOnlyComponent2>("unityComponent2");

            // Further setup
            var adapter = new UnityContainerAdapter(unityContainer);
            var provider = new ContainerExportProvider(adapter);
            var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            var container = new CompositionContainer(assemblyCatalog, provider);

            var component = container.GetExportedValue<IUnityOnlyComponent>("unityComponent2");
            Assert.That(component, Is.Not.Null);
            Assert.That(component.GetType(), Is.EqualTo(typeof(UnityOnlyComponent2)));
        }
        public void MefCannotResolveTypesRegisteredInUnityBeforeTrackingExtensionIsAddedTest()
        {
            // Setup
            var unityContainer = new UnityContainer();

            // Registration
            unityContainer.RegisterType<IUnityOnlyComponent, UnityOnlyComponent2>("unityComponent2");

            // Further setup
            var adapter = new UnityContainerAdapter(unityContainer);
            var provider = new ContainerExportProvider(adapter);
            var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            var container = new CompositionContainer(assemblyCatalog, provider);

            Assert.That(delegate
            {
                container.GetExportedValue<IUnityOnlyComponent>("unityComponent2");
            }, Throws.TypeOf<ImportCardinalityMismatchException>());
        }