public void Run_ValidContextAndAction_ReturnsExpected()
        {
            using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
            {
                Assert.True(host.TryGetExport(new CompositionContract(typeof(CompositionContext)), out object export));
                LifetimeContext context = Assert.IsType <LifetimeContext>(export);

                var results = new List <string>();
                void NonPrequisiteAction1() => results.Add("NonPrequisiteAction1");
                void NonPrequisiteAction2() => results.Add("NonPrequisiteAction2");

                void PostCompositionAction1() => results.Add("PostCompositionAction1");
                void PostCompositionAction2() => results.Add("PostCompositionAction2");

                object Activator(LifetimeContext activatorContext, CompositionOperation activatorOperation)
                {
                    Assert.Same(context, activatorContext);

                    activatorOperation.AddNonPrerequisiteAction(NonPrequisiteAction1);
                    activatorOperation.AddNonPrerequisiteAction(NonPrequisiteAction2);

                    activatorOperation.AddPostCompositionAction(PostCompositionAction1);
                    activatorOperation.AddPostCompositionAction(PostCompositionAction2);

                    return("Hi");
                }

                Assert.Equal("Hi", CompositionOperation.Run(context, Activator));
                Assert.Equal(new string[] { "NonPrequisiteAction1", "NonPrequisiteAction2", "PostCompositionAction1", "PostCompositionAction2" }, results);
            }
        }
Beispiel #2
0
        public override CompositeActivator RewriteActivator(
            TypeInfo partType,
            CompositeActivator activatorBody,
            IDictionary <string, object> partMetadata,
            IEnumerable <CompositionDependency> dependencies)
        {
            if (!ContractHelpers.IsShared(partMetadata))
            {
                return(activatorBody);
            }

            object sharingBoundaryMetadata;

            if (!partMetadata.TryGetValue(SharingBoundaryPartMetadataName, out sharingBoundaryMetadata))
            {
                sharingBoundaryMetadata = null;
            }

            var sharingBoundary = (string)sharingBoundaryMetadata;
            var sharingKey      = LifetimeContext.AllocateSharingId();

            return((c, o) =>
            {
                var scope = c.FindContextWithin(sharingBoundary);
                if (object.ReferenceEquals(scope, c))
                {
                    return scope.GetOrCreate(sharingKey, o, activatorBody);
                }
                else
                {
                    return CompositionOperation.Run(scope, (c1, o1) => c1.GetOrCreate(sharingKey, o1, activatorBody));
                }
            });
        }
Beispiel #3
0
        public void GetOrCreate_ValidActivatorAfterInitialization_Success()
        {
            using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
            {
                Assert.True(host.TryGetExport(new CompositionContract(typeof(CompositionContext)), out object export));
                LifetimeContext context = Assert.IsType<LifetimeContext>(export);

                CompositionOperation operation = null;
                var value = new object();
                object GetOrCreateActivate(LifetimeContext getOrCreateContext, CompositionOperation getOrCreateOperator)
                {
                    Assert.Same(context, getOrCreateContext);
                    Assert.Same(operation, getOrCreateOperator);

                    return value;
                }
                object Activator(LifetimeContext activatorContext, CompositionOperation activatorOperation)
                {
                    operation = activatorOperation;
                    Assert.Same(value, context.GetOrCreate(1, operation, GetOrCreateActivate));
                    return "Hi";
                }

                Assert.Equal("Hi", CompositionOperation.Run(context, Activator));
                Assert.Same(value, context.GetOrCreate(1, operation, GetOrCreateActivate));
            }
        }
Beispiel #4
0
        static object SubscriptionIdActivator(LifetimeContext context, CompositionOperation operation, IEnumerable <CompositionDependency> dependencies)
        {
            var dependency     = dependencies.Single().Target.GetDescriptor();
            var subscriptionId = (string)Run(context, dependency.Activator);

            return(new Guid(subscriptionId));
        }
        static ExportDescriptorPromise[] GetExportFactoryDescriptors <TProduct>(CompositionContract exportFactoryContract, DependencyAccessor definitionAccessor)
        {
            var productContract = exportFactoryContract.ChangeType(typeof(TProduct));
            var boundaries      = new string[0];

            IEnumerable <string> specifiedBoundaries;
            CompositionContract  unwrapped;

            if (exportFactoryContract.TryUnwrapMetadataConstraint(Constants.SharingBoundaryImportMetadataConstraintName, out specifiedBoundaries, out unwrapped))
            {
                productContract = unwrapped.ChangeType(typeof(TProduct));
                boundaries      = (specifiedBoundaries ?? new string[0]).ToArray();
            }

            return(definitionAccessor.ResolveDependencies("product", productContract, false)
                   .Select(d => new ExportDescriptorPromise(
                               exportFactoryContract,
                               Formatters.Format(typeof(ExportFactory <TProduct>)),
                               false,
                               () => new[] { d },
                               _ =>
            {
                var dsc = d.Target.GetDescriptor();
                var da = dsc.Activator;
                return ExportDescriptor.Create((c, o) =>
                {
                    return new ExportFactory <TProduct>(() => {
                        var lifetimeContext = new LifetimeContext(c, boundaries);
                        return Tuple.Create <TProduct, Action>((TProduct)CompositionOperation.Run(lifetimeContext, da), lifetimeContext.Dispose);
                    });
                },
                                               dsc.Metadata);
            }))
                   .ToArray());
        }
Beispiel #6
0
        static object PersistenceActivator(LifetimeContext context, CompositionOperation operation, IEnumerable <CompositionDependency> dependencies)
        {
            var map = dependencies.ToDictionary(d => d.Contract.ContractType, d => d.Target.GetDescriptor().Activator);
            var queueConfiguration      = (SqlMessageQueueConfiguration)Run(context, map[typeof(SqlMessageQueueConfiguration)]);
            var eventStoreConfiguration = (SqlEventStoreConfiguration)Run(context, map[typeof(SqlEventStoreConfiguration)]);
            var sagaConfiguration       = (SqlSagaStorageConfiguration)Run(context, map[typeof(SqlSagaStorageConfiguration)]);

            return(new SqlPersistence(queueConfiguration, eventStoreConfiguration, sagaConfiguration));
        }
Beispiel #7
0
        CompositeActivator CreateActivator(IEnumerable <CompositionDependency> dependencies)
        {
            var dependenciesByImport = dependencies.GroupBy(d => (ContractBasedImportDefinition)d.Site, d => d.Target.GetDescriptor());
            var prereqs    = dependenciesByImport.Where(d => d.Key.IsPrerequisite).ToArray();
            var nonprereqs = dependenciesByImport.Where(d => !d.Key.IsPrerequisite).ToArray();
            var unset      = _part.ImportDefinitions.Where(id => !prereqs.Concat(nonprereqs).Any(k => k.Key.Equals((ContractBasedImportDefinition)id))).ToArray();

            CompositeActivator construct = (c, o) =>
            {
                var result = _part.CreatePart();
                if (result is IDisposable)
                {
                    c.AddBoundInstance((IDisposable)result);
                }

                foreach (var pre in prereqs)
                {
                    result.SetImport(pre.Key, DependenciesToExports(c, pre));
                }

                foreach (var un in unset)
                {
                    result.SetImport(un, Enumerable.Empty <Export>());
                }

                o.AddNonPrerequisiteAction(() =>
                {
                    foreach (var np in nonprereqs)
                    {
                        result.SetImport(np.Key, DependenciesToExports(c, np));
                    }
                });

                o.AddPostCompositionAction(() =>
                {
                    result.Activate();
                });

                return(result);
            };

            if (!IsShared)
            {
                return(construct);
            }

            var sharingId = LifetimeContext.AllocateSharingId();
            CompositeActivator constructAndShare = (c, o) => c.GetOrCreate(sharingId, o, construct);

            return((c, o) =>
            {
                var scope = c.FindContextWithin(_boundary);
                return scope.Equals(c) ?
                constructAndShare(scope, o) :
                CompositionOperation.Run(scope, constructAndShare);
            });
        }
Beispiel #8
0
        static object SagaStorageConfigurationActivator(LifetimeContext context, CompositionOperation operation, IEnumerable <CompositionDependency> dependencies)
        {
            var dependency       = dependencies.Single().Target.GetDescriptor();
            var connectionString = (string)Run(context, dependency.Activator);
            var builder          = new SqlSagaStorageConfigurationBuilder();

            builder.HasConnectionString(connectionString);

            return(builder.CreateConfiguration());
        }
        public DelegateExportDescriptorProvider(Func <object> exportedInstanceFactory, Type contractType, string contractName, IDictionary <string, object> metadata, bool isShared)
            : base(contractType, contractName, metadata)
        {
            if (exportedInstanceFactory == null)
            {
                throw new ArgumentNullException("exportedInstanceFactory");
            }

            // Runs the factory method, validates the result and registers it for disposal if necessary.
            CompositeActivator constructor = (c, o) =>
            {
                var result = exportedInstanceFactory();
                if (result == null)
                {
                    throw new InvalidOperationException("Delegate factory returned null.");
                }

                if (result is IDisposable)
                {
                    c.AddBoundInstance((IDisposable)result);
                }

                return(result);
            };

            if (isShared)
            {
                var sharingId = LifetimeContext.AllocateSharingId();
                _activator = (c, o) =>
                {
                    // Find the root composition scope.
                    var scope = c.FindContextWithin(null);
                    if (scope == c)
                    {
                        // We're already in the root scope, create the instance
                        return(scope.GetOrCreate(sharingId, o, constructor));
                    }
                    else
                    {
                        // Composition is moving up the hierarchy of scopes; run
                        // a new operation in the root scope.
                        return(CompositionOperation.Run(scope, (c1, o1) => c1.GetOrCreate(sharingId, o1, constructor)));
                    }
                };
            }
            else
            {
                _activator = constructor;
            }
        }
Beispiel #10
0
        static object EventStoreConfigurationActivator(LifetimeContext context, CompositionOperation operation, IEnumerable <CompositionDependency> dependencies, string entityName)
        {
            var dependency       = dependencies.Single().Target.GetDescriptor();
            var connectionString = (string)Run(context, dependency.Activator);
            var builder          = new SqlEventStoreConfigurationBuilder();

            builder.HasConnectionString(connectionString);

            if (!string.IsNullOrEmpty(entityName))
            {
                builder.HasEntityName(entityName);
            }

            return(builder.CreateConfiguration());
        }
Beispiel #11
0
        public void GetOrCreate_NullActivator_ThrowsNullReferenceException()
        {
            using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
            {
                Assert.True(host.TryGetExport(new CompositionContract(typeof(CompositionContext)), out object export));
                LifetimeContext context = Assert.IsType<LifetimeContext>(export);

                object Activator(LifetimeContext activatorContext, CompositionOperation activatorOperation)
                {
                    Assert.Throws<NullReferenceException>(() => activatorContext.GetOrCreate(1, activatorOperation, null));
                    return "Hi";
                }

                Assert.Equal("Hi", CompositionOperation.Run(context, Activator));
            }
        }
        public void AddPostCompositionAction_NullAction_ThrowsArgumentNullException()
        {
            object Activator(LifetimeContext context, CompositionOperation operation)
            {
                AssertExtensions.Throws <ArgumentNullException>("action", () => operation.AddPostCompositionAction(null));
                return(null);
            }

            using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
            {
                Assert.True(host.TryGetExport(new CompositionContract(typeof(CompositionContext)), out object export));
                LifetimeContext context = Assert.IsType <LifetimeContext>(export);

                CompositionOperation.Run(context, Activator);
            }
        }
Beispiel #13
0
        static ExportDescriptorPromise[] GetLazyDefinitions <TValue, TMetadata>(CompositionContract lazyContract, DependencyAccessor definitionAccessor)
        {
            var metadataProvider = MetadataViewProvider.GetMetadataViewProvider <TMetadata>();

            return(definitionAccessor.ResolveDependencies("value", lazyContract.ChangeType(typeof(TValue)), false)
                   .Select(d => new ExportDescriptorPromise(
                               lazyContract,
                               Formatters.Format(typeof(Lazy <TValue, TMetadata>)),
                               false,
                               () => new[] { d },
                               _ =>
            {
                var dsc = d.Target.GetDescriptor();
                var da = dsc.Activator;
                return ExportDescriptor.Create((c, o) => {
                    return new Lazy <TValue, TMetadata>(() => (TValue)CompositionOperation.Run(c, da), metadataProvider(dsc.Metadata));
                }, dsc.Metadata);
            }))
                   .ToArray());
        }
 public object GetOrCreate(int sharingId, CompositionOperation operation, CompositeActivator creator);
        public void Run_NullActivator_ThrowsArgumentNullException()
        {
            using (CompositionHost host = CompositionHost.CreateCompositionHost(new ExportDescriptorProvider[0]))
            {
                Assert.True(host.TryGetExport(new CompositionContract(typeof(CompositionContext)), out object export));
                LifetimeContext context = Assert.IsType <LifetimeContext>(export);

                AssertExtensions.Throws <ArgumentNullException>("compositionRootActivator", () => CompositionOperation.Run(context, null));
            }
        }
Beispiel #16
0
 private object activator(LifetimeContext context, CompositionOperation operation)
 => Factory();
Beispiel #17
0
 private static object Activator(LifetimeContext context, CompositionOperation operation) => null;
 public object CompositeActivator(LifetimeContext context, CompositionOperation operation)
 {
     CalledCompositeActivator++;
     return(Result);
 }
 public void Run_NullOutmostContext_ThrowsArgumentNullException()
 {
     AssertExtensions.Throws <ArgumentNullException>("outermostLifetimeContext", () => CompositionOperation.Run(null, Activator));
 }
        // The source will only be asked for parts once per exportKey, but it is the
        // source's responsibility to return the same part multiple times when that part
        // has more than one export (not shown here.)
        //
        public override IEnumerable <ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor definitionAccessor)
        {
            if (contract.Equals(new CompositionContract(typeof(RequestListener))))
            {
                return new[] { RequestListenerPart(contract, definitionAccessor) }
            }
            ;

            if (contract.Equals(new CompositionContract(typeof(ConsoleLog))))
            {
                return new[] { ConsoleLogPart(contract, definitionAccessor) }
            }
            ;

            return(NoExportDescriptors);
        }

        // Console log is a disposable singleton (no boundaries)
        // that exports itself under its own concrete type.
        //
        ExportDescriptorPromise ConsoleLogPart(CompositionContract contract, DependencyAccessor definitionAccessor)
        {
            return(new ExportDescriptorPromise(
                       contract,
                       typeof(ConsoleLog).Name,
                       true,
                       NoDependencies,
                       _ =>
            {
                var sharingId = LifetimeContext.AllocateSharingId();

                return ExportDescriptor.Create((c, o) =>
                {
                    CompositeActivator activatorBody = (sc, so) =>
                    {
                        var result = new ConsoleLog();
                        c.AddBoundInstance(result);
                        return result;
                    };

                    var scope = c.FindContextWithin(null);
                    if (object.ReferenceEquals(scope, c))
                    {
                        return scope.GetOrCreate(sharingId, o, activatorBody);
                    }
                    else
                    {
                        return CompositionOperation.Run(scope, (c1, o1) => c1.GetOrCreate(sharingId, o1, activatorBody));
                    }
                }, NoMetadata);
            }));
        }

        // Non-shared part that exports itself and has a dependency on ConsoleLog.
        //
        ExportDescriptorPromise RequestListenerPart(CompositionContract contract, DependencyAccessor definitionAccessor)
        {
            return(new ExportDescriptorPromise(
                       contract,
                       typeof(RequestListener).Name,
                       false,
                       () => new[] { definitionAccessor.ResolveRequiredDependency("log", new CompositionContract(typeof(Lazy <ConsoleLog>)), true) },
                       dependencies =>
            {
                var logActivator = dependencies.Single().Target.GetDescriptor().Activator;
                return ExportDescriptor.Create((c, o) =>
                {
                    var log = (Lazy <ConsoleLog>)logActivator(c, o);
                    return new RequestListener(log);
                }, NoMetadata);
            }));
        }
    }
}
Beispiel #21
0
 static IEnumerable <Export> DependenciesToExports(LifetimeContext c, IGrouping <ContractBasedImportDefinition, ExportDescriptor> dependenciesByImport)
 {
     return(dependenciesByImport
            .Where(d => RequiredMetadataKeysArePresent(d.Metadata, dependenciesByImport.Key))
            .Select(d => new Export(dependenciesByImport.Key.ContractName, d.Metadata, () => CompositionOperation.Run(c, d.Activator))));
 }