Example #1
0
        private IEnumerable <Type> PrepareComposerTypes()
        {
            // create a list, remove those that cannot be enabled due to runtime level
            var composerTypeList = _composerTypes
                                   .Where(x =>
            {
                // use the min/max levels specified by the attribute if any
                // otherwise, min: user composers are Run, anything else is Unknown (always run)
                //            max: everything is Run (always run)
                var attr     = x.GetCustomAttribute <RuntimeLevelAttribute>();
                var minLevel = attr?.MinLevel ?? (x.Implements <IUserComposer>() ? RuntimeLevel.Run : RuntimeLevel.Unknown);
                var maxLevel = attr?.MaxLevel ?? RuntimeLevel.Run;
                return(_composition.RuntimeState.Level >= minLevel && _composition.RuntimeState.Level <= maxLevel);
            })
                                   .ToList();

            // enable or disable composers
            EnableDisableComposers(composerTypeList);

            // sort the composers according to their dependencies
            var requirements = new Dictionary <Type, List <Type> >();

            foreach (var type in composerTypeList)
            {
                requirements[type] = null;
            }
            foreach (var type in composerTypeList)
            {
                GatherRequirementsFromRequireAttribute(type, composerTypeList, requirements);
                GatherRequirementsFromRequiredByAttribute(type, composerTypeList, requirements);
            }

            // only for debugging, this is verbose
            //_logger.Debug<Composers>(GetComposersReport(requirements));

            // sort composers
            var graph = new TopoGraph <Type, KeyValuePair <Type, List <Type> > >(kvp => kvp.Key, kvp => kvp.Value);

            graph.AddItems(requirements);
            List <Type> sortedComposerTypes;

            try
            {
                sortedComposerTypes = graph.GetSortedItems().Select(x => x.Key).ToList();
            }
            catch (Exception e)
            {
                // in case of an error, force-dump everything to log
                _logger.Info <Composers>("Composer Report:\r\n{ComposerReport}", GetComposersReport(requirements));
                _logger.Error <Composers>(e, "Failed to sort composers.");
                throw;
            }

            // bit verbose but should help for troubleshooting
            //var text = "Ordered Composers: " + Environment.NewLine + string.Join(Environment.NewLine, sortedComposerTypes) + Environment.NewLine;
            _logger.Debug <Composers>("Ordered Composers: {SortedComposerTypes}", sortedComposerTypes);

            return(sortedComposerTypes);
        }
Example #2
0
        internal IEnumerable <Type> SortComposers(Dictionary <Type, List <Type> > requirements)
        {
            // sort composers
            var graph = new TopoGraph <Type, KeyValuePair <Type, List <Type> > >(kvp => kvp.Key, kvp => kvp.Value);

            graph.AddItems(requirements);
            List <Type> sortedComposerTypes;

            try
            {
                sortedComposerTypes = graph.GetSortedItems().Select(x => x.Key).Where(x => !x.IsInterface).ToList();
            }
            catch (Exception e)
            {
                // in case of an error, force-dump everything to log
                _logger.LogInformation("Composer Report:\r\n{ComposerReport}", GetComposersReport(requirements));
                _logger.LogError(e, "Failed to sort composers.");
                throw;
            }

            return(sortedComposerTypes);
        }