public IEnumerable <string> GenerateAdditionalSourceCodeItems( Tuple <string, string[]> bondManifest, string[] manifestIds) { if (bondManifest.Item1 == null) { return(new string[0]); } if (manifestIds.Length == 1) { var map = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); foreach (var className in bondManifest.Item2) { var name = bondManifest.Item1 + "." + className; var id = BondIdentifierHelpers.GenerateGuidFromName(name); map[name] = id.ToString(); } if (!string.Equals( manifestIds[0], map[bondManifest.Item1 + "." + bondManifest.Item2.Last()], StringComparison.OrdinalIgnoreCase)) { return(new string[] { GenerateManifestOverrideCSharpClass(bondManifest.Item1, bondManifest.Item2.Last(), manifestIds[0]), }); } } return(new string[0]); }
public void Initialize(string targetDir, params string[] files) { // Don't validate targetDir for empty. it will be created. if (targetDir == null) { throw new ArgumentNullException("targetDir"); } if (files == null || files.Length <= 0) { throw new ArgumentNullException("files"); } this.CacheDirectory = ResolveCacheDirectory(targetDir); if (!Directory.Exists(CacheDirectory)) { Directory.CreateDirectory(CacheDirectory); } else { Utilities.EmptyDirectory(this.CacheDirectory); } // Get all manifests. var manifestsFromFiles = BinaryEtwObservable.BinaryManifestFromSequentialFiles(files) .ToEnumerable() .Where(a => !string.IsNullOrWhiteSpace(a.Manifest)) .GroupBy(manifest => manifest.ManifestId, StringComparer.OrdinalIgnoreCase) .Select(grp => grp.First()) .ToArray(); if (manifestsFromFiles.Length == 0) { throw new Exception("No Bond manifests found. Ensure that the Bond manifests are written to the ETL file."); } int counter = 0; foreach (var manifestItem in manifestsFromFiles) { var codeSources = new List <string>(); var namespaceAndClasses = this.ParseClassNames(manifestItem.Manifest); var assembliesOfThisManifest = new List <string>(); if (!this.AreAnyTypesAlreadyInCache(namespaceAndClasses.Item2)) { string bondFileName = Path.Combine(CacheDirectory, "BondTypes" + counter + ".bond"); counter++; File.WriteAllText(bondFileName, manifestItem.Manifest); var codeGenerated = this.GenerateCSharpCode(bondFileName); if (!string.IsNullOrWhiteSpace(codeGenerated)) { codeSources.Add(codeGenerated); foreach (var @class in namespaceAndClasses.Item2) { var completeName = namespaceAndClasses.Item1 + "." + @class; var id = BondIdentifierHelpers.GenerateGuidFromName(@class.ToUpperInvariant()); // case when single manifest has multiple structs. if (namespaceAndClasses.Item2.Length > 1 && !string.Equals(manifestItem.ManifestId, id.ToString(), StringComparison.OrdinalIgnoreCase)) { codeSources.Add(GenerateAdditionalSourceCodeItems(namespaceAndClasses.Item1, @class, id)); this.Cache.Add(new TypeCacheItem { Manifest = new EventManifest { ActivityId = manifestItem.ActivityId, Manifest = manifestItem.Manifest, ManifestId = id.ToString(), OccurenceFileTimeUtc = manifestItem.OccurenceFileTimeUtc, Protocol = manifestItem.Protocol, ReceiveFileTimeUtc = manifestItem.ReceiveFileTimeUtc, Source = manifestItem.Source, }, }); } else { codeSources.Add(GenerateAdditionalSourceCodeItems(namespaceAndClasses.Item1, @class, new Guid(manifestItem.ManifestId))); this.Cache.Add(new TypeCacheItem { Manifest = new EventManifest { ActivityId = manifestItem.ActivityId, Manifest = manifestItem.Manifest, ManifestId = manifestItem.ManifestId, OccurenceFileTimeUtc = manifestItem.OccurenceFileTimeUtc, Protocol = manifestItem.Protocol, ReceiveFileTimeUtc = manifestItem.ReceiveFileTimeUtc, Source = manifestItem.Source, }, }); } } // After building the assembly, the types will be available. string asm = Path.Combine(CacheDirectory, bondFileName + ".dll"); this.OutputAssembly(codeSources.ToArray(), asm); assembliesOfThisManifest.Add(asm); try { var types = assembliesOfThisManifest.Select(Assembly.LoadFile) .SelectMany(a => a.GetTypes().Where(type => type.IsPublic)) .ToArray(); foreach (var item in types) { var targetCacheItem = this.FindMatchOrDefault(item.GUID.ToString()); if (targetCacheItem != null) { targetCacheItem.Type = item; } } } catch { //Ignore this type throw; } } } } }