예제 #1
0
        private IEnumerable<AssetIdentifier> DiscoverAssets(IAssetResolver assetResolver,
                                                            IEnumerable<Assembly> assemblies)
        {
            TraceSources.GeneratorSource.TraceEvent(TraceEventType.Start, 0, "Discovering assets");
            HashSet<AssetIdentifier> distinctSet = new HashSet<AssetIdentifier>();
            IFilterContext filterContext = new FilterContext(this._cache, this._container, assetResolver, FilterState.Discovery);

            // find and filter all types from all assemblies 
            foreach (Assembly asm in assemblies)
            {
                foreach (Type t in asm.GetTypes())
                {
                    // check if type survives filtering
                    AssetIdentifier typeAsset = AssetIdentifier.FromMemberInfo(t);

                    if (this.IsFiltered(filterContext, typeAsset)) 
                        continue;

                    /* type was not filtered */
                    TraceSources.GeneratorSource.TraceEvent(TraceEventType.Information, 0, "{0}", typeAsset.AssetId);

                    // generate namespace hierarchy
                    if (!string.IsNullOrEmpty(t.Namespace))
                    {
                        Version nsVersion = t.Module.Assembly.GetName().Version;

                        string[] fragments = t.Namespace.Split('.');
                        for (int i = fragments.Length; i > 0; i--)
                        {
                            string ns = string.Join(".", fragments, 0, i);
                            AssetIdentifier nsAsset = AssetIdentifier.FromNamespace(ns, nsVersion);
                            if (distinctSet.Add(nsAsset))
                                yield return nsAsset;
                        }
                    }

                    if (distinctSet.Add(typeAsset))
                        yield return typeAsset;


                    MemberInfo[] members =
                        t.GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public |
                                     BindingFlags.NonPublic);

                    foreach (MemberInfo member in members)
                    {
                        AssetIdentifier memberAsset = AssetIdentifier.FromMemberInfo(member);
                        if (this.IsFiltered(filterContext, memberAsset)) 
                            continue;

                        TraceSources.GeneratorSource.TraceEvent(TraceEventType.Information, 0, "{0}",
                                                                memberAsset.AssetId);
                        if (distinctSet.Add(memberAsset))
                            yield return memberAsset;
                    }
                }

                yield return AssetIdentifier.FromAssembly(asm);
            }

            TraceSources.GeneratorSource.TraceEvent(TraceEventType.Stop, 0, "Discovering assets");
        }
예제 #2
0
        public bool IsFiltered(AssetIdentifier assetId)
        {
            IFilterContext filterContext = new FilterContext(this.Cache, this.Container, this.AssetResolver, FilterState.Generating);
            for (int i = 0; i < this._filters.Length; i++)
            {
                if (this._filters[i].Filter(filterContext, assetId))
                {
                    TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose,
                                        0,
                                        "{0} - Filtered by {1}",
                                        assetId.AssetId, this._filters[i]);
                    return true;
                }
            }

            return false;
        }
예제 #3
0
        public XDocument Generate(string path)
        {
            TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose, 0, "Enrichers:");

            for (int i = 0; i < this.Enrichers.Count; i++)
            {
                IEnricher enricher = this.Enrichers[i];
                TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose,
                                                        0,
                                                        "[{0}] {1}",
                                                        i,
                                                        enricher.GetType().FullName);
            }

            TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose, 0, "Filters:");
            for (int i = 0; i < this.AssetFilters.Count; i++)
            {
                TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose,
                                                        0,
                                                        "[{0}] {1}",
                                                        i,
                                                        this.AssetFilters[i].GetType().FullName);
            }

            XDocument ret = new XDocument();

            IAssemblyLoader assemblyLoader = new ReflectionOnlyAssemblyLoader(
                this._cache,
                this._assemblyPaths.Select(Path.GetDirectoryName));

            Assembly assembly = assemblyLoader.LoadFrom(path);
            Asset assemblyAsset = ReflectionServices.GetAsset(assembly);

            XNamespace defaultNs = string.Empty;
            // pass in assemblyLoader instead
            IAssetExplorer assetExplorer = new ReflectionExplorer(assemblyLoader);
            IFilterContext filterContext = new FilterContext(this._cache,
                                                             this._container,
                                                             FilterState.Discovery,
                                                             this._filters.ToArray());
            // collect phase zero assets
            var assets = this.DiscoverAssets(assemblyAsset, assetExplorer, filterContext);

            // initiate output document creation
            ret.Add(new XElement(defaultNs + "bundle"));


            IProcessingContext pctx = new ProcessingContext(this._cache,
                                                            this._container,
                                                            this._filters,
                                                            assemblyLoader,
                                                            ret.Root,
                                                            null,
                                                            -1,
                                                            assetExplorer);

            foreach (IEnricher enricher in this._enrichers)
                enricher.RegisterNamespace(pctx);

            // asset related classes
            HashSet<Asset> emittedAssets = new HashSet<Asset>();

            TraceSources.GeneratorSource.TraceEvent(TraceEventType.Start, 0, "Generating document");

            int phase = 0;
            HashSet<Asset> referencedAssets = new HashSet<Asset>();

            long lastProgressOutput = Stopwatch.GetTimestamp();
            // main output loop
            while (assets.Count > 0)
            {
                int phaseAssetCount = 0;
                using (TraceSources.GeneratorSource.TraceActivity("Phase {0} ({1:N0} assets)", phase, assets.Count))
                {
                    foreach (Asset asset in assets)
                    {
                        // skip already emitted assets
                        if (!emittedAssets.Add(asset))
                            continue;

                        phaseAssetCount++;

                        if (((Stopwatch.GetTimestamp() - lastProgressOutput) / (double)Stopwatch.Frequency) > 5.0)
                        {
                            TraceSources.GeneratorSource.TraceEvent(TraceEventType.Information, 0,
                                                                    "Phase {0} progress {1:P1} ({2:N0}/{3:N0})",
                                                                    phase,
                                                                    phaseAssetCount / (double)assets.Count,
                                                                    phaseAssetCount,
                                                                    assets.Count);

                            lastProgressOutput = Stopwatch.GetTimestamp();
                        }

                        TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose, 0, "Generating {0}", asset);

                        // get hierarchy
                        LinkedList<Asset> hierarchy = new LinkedList<Asset>();

                        foreach (Asset hierarchyAsset in assetExplorer.GetAssetHierarchy(asset))
                            hierarchy.AddFirst(hierarchyAsset);

                        if (hierarchy.First != null)
                        {
                            this.BuildHierarchy(ret.Root,
                                                hierarchy.First,
                                                referencedAssets,
                                                emittedAssets,
                                                phase, assetExplorer);
                        }
                    }

                    ++phase;
                    assets.Clear();
                    referencedAssets.ExceptWith(emittedAssets);
                    assets = referencedAssets.ToList();
                    referencedAssets.Clear();
                }
            }

            TraceSources.GeneratorSource.TraceEvent(TraceEventType.Stop, 0, "Generating document");
            return ret;
        }