Example #1
0
        private Tuple <ITargetBlock <Assembly>, Task <DiscoveredParts> > CreateAssemblyDiscoveryBlockChain(IProgress <DiscoveryProgress> progress, CancellationToken cancellationToken)
        {
            var progressFilter = new ProgressFilter(progress);

            var tuple         = this.CreateDiscoveryBlockChain(false, progressFilter, cancellationToken);
            var exceptions    = new List <PartDiscoveryException>();
            var assemblyBlock = new TransformManyBlock <Assembly, Type>(
                a =>
            {
                IReadOnlyCollection <Type> types;
                try
                {
                    // Fully realize any enumerable now so that we can catch the exception rather than
                    // leave it to dataflow to catch it.
                    types = this.GetTypes(a).ToList();
                }
                catch (ReflectionTypeLoadException ex)
                {
                    var partDiscoveryException = new PartDiscoveryException(string.Format(CultureInfo.CurrentCulture, Strings.ReflectionTypeLoadExceptionWhileEnumeratingTypes, a.Location), ex)
                    {
                        AssemblyPath = a.Location
                    };
                    lock (exceptions)
                    {
                        exceptions.Add(partDiscoveryException);
                    }

                    types = ex.Types.Where(t => t != null).ToList();
                }
                catch (Exception ex)
                {
                    var partDiscoveryException = new PartDiscoveryException(string.Format(CultureInfo.CurrentCulture, Strings.UnableToEnumerateTypes, a.Location), ex)
                    {
                        AssemblyPath = a.Location
                    };
                    lock (exceptions)
                    {
                        exceptions.Add(partDiscoveryException);
                    }

                    return(Enumerable.Empty <Type>());
                }

                progressFilter.OnDiscoveredMoreTypes(types.Count);
                return(types);
            },
                new ExecutionDataflowBlockOptions
            {
                MaxDegreeOfParallelism = Debugger.IsAttached ? 1 : Environment.ProcessorCount,
                CancellationToken      = cancellationToken,
            });

            assemblyBlock.LinkTo(tuple.Item1, new DataflowLinkOptions {
                PropagateCompletion = true
            });

            var tcs = new TaskCompletionSource <DiscoveredParts>();

            Task.Run(async delegate
            {
                try
                {
                    var parts = await tuple.Item2.ConfigureAwait(false);
                    tcs.SetResult(parts.Merge(new DiscoveredParts(Enumerable.Empty <ComposablePartDefinition>(), exceptions)));
                }
                catch (Exception ex)
                {
                    tcs.SetException(ex);
                }
            });

            return(Tuple.Create <ITargetBlock <Assembly>, Task <DiscoveredParts> >(assemblyBlock, tcs.Task));
        }