private void OutputProjectInfoRecords(ScanDescriptor scanRecord) { var flat = new SortedDictionary <String, Object>(); AddPrimaryKeyElements(scanRecord, flat); flat.Add(PropertyKeys.KEY_PRESET, scanRecord.Project.PresetName); flat.Add("Policies", scanRecord.Project.Policies); foreach (var lastScanProduct in scanRecord.Project.LatestScanDateByProduct.Keys) { flat.Add($"{lastScanProduct}_LastScanDate", scanRecord.Project.LatestScanDateByProduct[lastScanProduct]); } foreach (var scanCountProduct in scanRecord.Project.ScanCountByProduct.Keys) { flat.Add($"{scanCountProduct}_Scans", scanRecord.Project.ScanCountByProduct[scanCountProduct]); } if (scanRecord.Project.CustomFields != null && scanRecord.Project.CustomFields.Count > 0) { flat.Add(PropertyKeys.KEY_CUSTOMFIELDS, scanRecord.Project.CustomFields); } ProjectInfoOut.write(flat); }
public static void ScaReportOutput(ScanDescriptor sd, Transformer inst) { Dictionary <String, CxOsaLicenses.License> licenseIndex = new Dictionary <string, CxOsaLicenses.License>(); Dictionary <String, int> licenseCount = new Dictionary <string, int>(); try { var licenses = CxOsaLicenses.GetLicenses(inst.RestContext, inst.CancelToken, sd.ScanId); foreach (var l in licenses) { licenseIndex.Add(l.LicenseId, l); if (licenseCount.ContainsKey(l.RiskLevel)) { licenseCount[l.RiskLevel]++; } else { licenseCount.Add(l.RiskLevel, 1); } } } catch (Exception ex) { _log.Warn($"Could not obtain license data for scan {sd.ScanId} in project " + $"{sd.Project.ProjectId}: {sd.Project.ProjectName}. License data will not be" + $" available.", ex); } Dictionary <String, CxOsaLibraries.Library> libraryIndex = new Dictionary <string, CxOsaLibraries.Library>(); try { var libraries = CxOsaLibraries.GetLibraries(inst.RestContext, inst.CancelToken, sd.ScanId); foreach (var lib in libraries) { libraryIndex.Add(lib.LibraryId, lib); } } catch (Exception ex) { _log.Warn($"Could not obtain library data for scan {sd.ScanId} in project " + $"{sd.Project.ProjectId}: {sd.Project.ProjectName}. Library data will not be" + $" available.", ex); } OutputScaScanSummary(sd, inst, licenseCount); OutputScaScanDetails(sd, inst, licenseIndex, libraryIndex); }
private void AddPrimaryKeyElements(ScanDescriptor rec, IDictionary <String, Object> flat) { flat.Add(PropertyKeys.KEY_PROJECTID, rec.Project.ProjectId); flat.Add(PropertyKeys.KEY_PROJECTNAME, rec.Project.ProjectName); flat.Add(PropertyKeys.KEY_TEAMNAME, rec.Project.TeamName); if (!String.IsNullOrEmpty(InstanceId)) { flat.Add(PropertyKeys.KEY_INSTANCEID, InstanceId); } }
private static void AddPolicyViolationProperties(ScanDescriptor scanRecord, IDictionary <String, Object> rec) { if (scanRecord.HasPoliciesApplied) { rec.Add("PoliciesViolated", scanRecord.PoliciesViolated); rec.Add("RulesViolated", scanRecord.RulesViolated); rec.Add("PolicyViolations", scanRecord.Violations); } }
private static void AddPolicyViolationProperties(ScanDescriptor scanRecord, IDictionary <string, string> rec) { if (scanRecord.HasPoliciesApplied) { rec.Add("PoliciesViolated", Convert.ToString(scanRecord.PoliciesViolated)); rec.Add("RulesViolated", Convert.ToString(scanRecord.RulesViolated)); rec.Add("PolicyViolations", Convert.ToString(scanRecord.Violations)); } }
private void OutputPolicyViolationDetails(ScanDescriptor scan) { var header = new SortedDictionary <String, Object>(); AddPrimaryKeyElements(scan, header); header.Add(PropertyKeys.KEY_SCANID, scan.ScanId); header.Add(PropertyKeys.KEY_SCANPRODUCT, scan.ScanProduct); header.Add(PropertyKeys.KEY_SCANTYPE, scan.ScanType); var violatedRules = PolicyViolations[scan.Project.ProjectId]. GetViolatedRulesByScanId(scan.ScanId); if (violatedRules != null) { foreach (var rule in violatedRules) { var flat = new SortedDictionary <String, Object>(header); flat.Add("PolicyId", rule.PolicyId); flat.Add("PolicyName", Policies.GetPolicyById(rule.PolicyId).Name); flat.Add("RuleId", rule.RuleId); flat.Add("RuleName", rule.Name); flat.Add("RuleDescription", rule.Description); flat.Add("RuleType", rule.RuleType); flat.Add("RuleCreateDate", rule.CreatedOn); flat.Add("FirstViolationDetectionDate", rule.FirstDetectionDate); flat.Add("ViolationName", rule.ViolationName); if (rule.ViolationOccured.HasValue) { flat.Add("ViolationOccurredDate", rule.ViolationOccured.Value); } if (rule.ViolationRiskScore.HasValue) { flat.Add("ViolationRiskScore", rule.ViolationRiskScore.Value); } flat.Add("ViolationSeverity", rule.ViolationSeverity); if (rule.ViolationSource != null) { flat.Add("ViolationSource", rule.ViolationSource); } flat.Add("ViolationState", rule.ViolationState); flat.Add("ViolationStatus", rule.ViolationStatus); if (rule.ViolationType != null) { flat.Add("ViolationType", rule.ViolationType); } PolicyViolationDetailOut.write(flat); } } }
private static void OutputScaScanSummary(ScanDescriptor sd, Transformer inst, Dictionary <string, int> licenseCount) { SortedDictionary <String, String> flat = new SortedDictionary <string, string>(); AddPrimaryKeyElements(sd, flat); AddPolicyViolationProperties(sd, flat); flat.Add(PropertyKeys.KEY_SCANID, sd.ScanId); flat.Add(PropertyKeys.KEY_SCANSTART, inst.ScaScanCache[sd.ScanId].StartTime. ToString(DATE_FORMAT)); flat.Add(PropertyKeys.KEY_SCANFINISH, inst.ScaScanCache[sd.ScanId].FinishTime. ToString(DATE_FORMAT)); foreach (var k in licenseCount.Keys) { flat.Add($"Legal{k}", Convert.ToString(licenseCount[k])); } try { var summary = CxScaSummaryReport.GetReport(inst.RestContext, inst.CancelToken, sd.ScanId); flat.Add("HighVulnerabilityLibraries", Convert.ToString(summary.HighVulnerabilityLibraries)); flat.Add("LowVulnerabilityLibraries", Convert.ToString(summary.LowVulnerabilityLibraries)); flat.Add("MediumVulnerabilityLibraries", Convert.ToString(summary.MediumVulnerabilityLibraries)); flat.Add("NonVulnerableLibraries", Convert.ToString(summary.NonVulnerableLibraries)); flat.Add("TotalHighVulnerabilities", Convert.ToString(summary.TotalHighVulnerabilities)); flat.Add("TotalLibraries", Convert.ToString(summary.TotalLibraries)); flat.Add("TotalLowVulnerabilities", Convert.ToString(summary.TotalLowVulnerabilities)); flat.Add("TotalMediumVulnerabilities", Convert.ToString(summary.TotalMediumVulnerabilities)); flat.Add("VulnerabilityScore", summary.VulnerabilityScore); flat.Add("VulnerableAndOutdated", Convert.ToString(summary.VulnerableAndOutdated)); flat.Add("VulnerableAndUpdated", Convert.ToString(summary.VulnerableAndUpdated)); } catch (Exception ex) { _log.Warn($"Error obtaining summary report for SCA scan {sd.ScanId} " + $"in project {sd.Project.ProjectName}", ex); } inst.ScaScanSummaryOut.write(flat); }
public static void SastReportOutput(ScanDescriptor scan, Transformer inst) { _log.Debug($"Retrieving XML Report for scan {scan.ScanId}"); try { using (var report = CxSastXmlReport.GetXmlReport(inst.RestContext, inst.CancelToken, scan.ScanId)) { _log.Debug($"XML Report for scan {scan.ScanId} retrieved."); _log.Debug($"Processing XML report for scan {scan.ScanId}"); inst.ProcessSASTReport(scan, report); _log.Debug($"XML Report for scan {scan.ScanId} processed."); } inst.OutputSASTScanSummary(scan); } catch (AggregateException aex) { _log.Warn($"Multiple exceptions caught attempting to retrieve the SAST XML report for {scan.ScanId}" + $" in project {scan.Project.ProjectId}: {scan.Project.ProjectName}. "); _log.Warn("BEGIN exception report"); int exCount = 0; aex.Handle((x) => { _log.Warn($"Exception #{++exCount}", x); return(true); }); _log.Warn("END exception report"); } catch (Exception ex) { _log.Warn($"Error attempting to retrieve the SAST XML report for {scan.ScanId}" + $" in project {scan.Project.ProjectId}: {scan.Project.ProjectName}. ", ex); } }
private void OutputSASTScanSummary(ScanDescriptor scanRecord) { if (SastScanSummaryOut == null) { return; } var flat = new SortedDictionary <String, Object>(); AddPrimaryKeyElements(scanRecord, flat); flat.Add(PropertyKeys.KEY_SCANID, scanRecord.ScanId); flat.Add(PropertyKeys.KEY_SCANPRODUCT, scanRecord.ScanProduct); flat.Add(PropertyKeys.KEY_SCANTYPE, scanRecord.ScanType); flat.Add(PropertyKeys.KEY_SCANFINISH, scanRecord.FinishedStamp); flat.Add(PropertyKeys.KEY_SCANSTART, SastScanCache[scanRecord.ScanId].StartTime); flat.Add(PropertyKeys.KEY_ENGINESTART, SastScanCache[scanRecord.ScanId].EngineStartTime); flat.Add(PropertyKeys.KEY_ENGINEFINISH, SastScanCache[scanRecord.ScanId].EngineFinishTime); flat.Add(PropertyKeys.KEY_SCANRISK, SastScanCache[scanRecord.ScanId].ScanRisk); flat.Add(PropertyKeys.KEY_SCANRISKSEV, SastScanCache[scanRecord.ScanId].ScanRiskSeverity); flat.Add("LinesOfCode", SastScanCache[scanRecord.ScanId].LinesOfCode); flat.Add("FailedLinesOfCode", SastScanCache[scanRecord.ScanId].FailedLinesOfCode); flat.Add("FileCount", SastScanCache[scanRecord.ScanId].FileCount); flat.Add("CxVersion", SastScanCache[scanRecord.ScanId].CxVersion); flat.Add("Languages", SastScanCache[scanRecord.ScanId].Languages); flat.Add(PropertyKeys.KEY_PRESET, scanRecord.Preset); flat.Add("Initiator", scanRecord.Initiator); flat.Add("DeepLink", scanRecord.DeepLink); flat.Add("ScanTime", scanRecord.ScanTime); flat.Add("ReportCreationTime", scanRecord.ReportCreateTime); flat.Add("ScanComments", scanRecord.Comments); flat.Add("SourceOrigin", scanRecord.SourceOrigin); foreach (var sev in scanRecord.SeverityCounts.Keys) { flat.Add(sev, scanRecord.SeverityCounts[sev]); } AddPolicyViolationProperties(scanRecord, flat); SastScanSummaryOut.write(flat); }
private void OutputScaScanSummary(IOutputTransaction trx, ScanDescriptor sd, Dictionary <string, int> licenseCount) { var flat = new SortedDictionary <String, Object>(); AddPrimaryKeyElements(sd.Project, flat); AddPolicyViolationProperties(sd, flat); flat.Add(PropertyKeys.KEY_SCANID, sd.ScanId); flat.Add(PropertyKeys.KEY_SCANSTART, ScaScanCache[sd.ScanId].StartTime); flat.Add(PropertyKeys.KEY_SCANFINISH, ScaScanCache[sd.ScanId].FinishTime); foreach (var k in licenseCount.Keys) { flat.Add($"Legal{k}", licenseCount[k]); } try { var summary = CxOsaSummaryReport.GetReport(RestContext, CancelToken, sd.ScanId); flat.Add("HighVulnerabilityLibraries", summary.HighVulnerabilityLibraries); flat.Add("LowVulnerabilityLibraries", summary.LowVulnerabilityLibraries); flat.Add("MediumVulnerabilityLibraries", summary.MediumVulnerabilityLibraries); flat.Add("NonVulnerableLibraries", summary.NonVulnerableLibraries); flat.Add("TotalHighVulnerabilities", summary.TotalHighVulnerabilities); flat.Add("TotalLibraries", summary.TotalLibraries); flat.Add("TotalLowVulnerabilities", summary.TotalLowVulnerabilities); flat.Add("TotalMediumVulnerabilities", summary.TotalMediumVulnerabilities); flat.Add("VulnerabilityScore", summary.VulnerabilityScore); flat.Add("VulnerableAndOutdated", summary.VulnerableAndOutdated); flat.Add("VulnerableAndUpdated", summary.VulnerableAndUpdated); } catch (Exception ex) { _log.Warn($"Error obtaining summary report for SCA scan {sd.ScanId} " + $"in project {sd.Project.ProjectName}", ex); } trx.write(ScaScanSummaryOut, flat); }
public static void SastReportOutput(ScanDescriptor scan, Transformer inst) { _log.Debug($"Retrieving XML Report for scan {scan.ScanId}"); try { using (var report = CxSastXmlReport.GetXmlReport(inst.RestContext, inst.CancelToken, scan.ScanId)) { _log.Debug($"XML Report for scan {scan.ScanId} retrieved."); _log.Debug($"Processing XML report for scan {scan.ScanId}"); inst.ProcessSASTReport(scan, report); _log.Debug($"XML Report for scan {scan.ScanId} processed."); } inst.OutputSASTScanSummary(scan); } catch (Exception ex) { _log.Warn($"Error attempting to retrieve the SAST XML report for {scan.ScanId}" + $" in project {scan.Project.ProjectId}: {scan.Project.ProjectName}. ", ex); } }
private void OutputProjectInfoRecords(ScanDescriptor scanRecord) { SortedDictionary <String, String> flat = new SortedDictionary <string, string>(); AddPrimaryKeyElements(scanRecord, flat); flat.Add(PropertyKeys.KEY_PRESET, scanRecord.Project.PresetName); flat.Add("Policies", scanRecord.Project.Policies); foreach (var lastScanProduct in scanRecord.Project.LatestScanDateByProduct.Keys) { flat.Add($"{lastScanProduct}_LastScanDate", scanRecord.Project.LatestScanDateByProduct[lastScanProduct].ToString(DATE_FORMAT)); } foreach (var scanCountProduct in scanRecord.Project.ScanCountByProduct.Keys) { flat.Add($"{scanCountProduct}_Scans", scanRecord.Project.ScanCountByProduct[scanCountProduct].ToString()); } ProjectInfoOut.write(flat); }
private void ProcessSASTReport(ScanDescriptor scan, Stream report) { var reportRec = new SortedDictionary <String, Object>(); AddPrimaryKeyElements(scan, reportRec); reportRec.Add(PropertyKeys.KEY_SCANID, scan.ScanId); reportRec.Add(PropertyKeys.KEY_SCANPRODUCT, scan.ScanProduct); reportRec.Add(PropertyKeys.KEY_SCANTYPE, scan.ScanType); reportRec.Add(PropertyKeys.KEY_SCANFINISH, scan.FinishedStamp); SortedDictionary <String, Object> curResultRec = null; SortedDictionary <String, Object> curQueryRec = null; SortedDictionary <String, Object> curPath = null; SortedDictionary <String, Object> curPathNode = null; bool inSnippet = false; using (XmlReader xr = XmlReader.Create(report)) { while (xr.Read()) { if (xr.NodeType == XmlNodeType.Element) { if (xr.Name.CompareTo("CxXMLResults") == 0) { _log.Debug($"[Scan: {scan.ScanId}] Processing attributes in CxXMLResults."); scan.Preset = xr.GetAttribute("Preset"); scan.Initiator = xr.GetAttribute("InitiatorName"); scan.DeepLink = xr.GetAttribute("DeepLink"); scan.ScanTime = xr.GetAttribute("ScanTime"); scan.ReportCreateTime = DateTime.Parse(xr.GetAttribute("ReportCreationTime")); scan.Comments = xr.GetAttribute("ScanComments"); scan.SourceOrigin = xr.GetAttribute("SourceOrigin"); continue; } if (xr.Name.CompareTo("Query") == 0) { _log.Debug($"[Scan: {scan.ScanId}] Processing attributes in Query " + $"[{xr.GetAttribute("id")} - {xr.GetAttribute("name")}]."); curQueryRec = new SortedDictionary <String, Object> (reportRec); curQueryRec.Add("QueryCategories", xr.GetAttribute("categories")); curQueryRec.Add("QueryId", xr.GetAttribute("id")); curQueryRec.Add("QueryCweId", xr.GetAttribute("cweId")); curQueryRec.Add("QueryName", xr.GetAttribute("name")); curQueryRec.Add("QueryGroup", xr.GetAttribute("group")); curQueryRec.Add("QuerySeverity", xr.GetAttribute("Severity")); curQueryRec.Add("QueryLanguage", xr.GetAttribute("Language")); curQueryRec.Add("QueryVersionCode", xr.GetAttribute("QueryVersionCode")); continue; } if (xr.Name.CompareTo("Result") == 0) { _log.Debug($"[Scan: {scan.ScanId}] Processing attributes in Result " + $"[{xr.GetAttribute("NodeId")}]."); scan.IncrementSeverity(xr.GetAttribute("Severity")); curResultRec = new SortedDictionary <String, Object>(curQueryRec); curResultRec.Add("VulnerabilityId", xr.GetAttribute("NodeId")); curResultRec.Add("SinkFileName", xr.GetAttribute("FileName")); curResultRec.Add("Status", xr.GetAttribute("Status")); curResultRec.Add("SinkLine", xr.GetAttribute("Line")); curResultRec.Add("SinkColumn", xr.GetAttribute("Column")); curResultRec.Add("FalsePositive", xr.GetAttribute("FalsePositive")); curResultRec.Add("ResultSeverity", xr.GetAttribute("Severity")); // TODO: Translate state number to an appropriate string curResultRec.Add("State", xr.GetAttribute("state")); curResultRec.Add("Remark", xr.GetAttribute("Remark")); curResultRec.Add("ResultDeepLink", xr.GetAttribute("DeepLink")); continue; } if (xr.Name.CompareTo("Path") == 0) { curPath = new SortedDictionary <String, Object>(curResultRec); curPath.Add("ResultId", xr.GetAttribute("ResultId")); curPath.Add("PathId", xr.GetAttribute("PathId")); curPath.Add(PropertyKeys.KEY_SIMILARITYID, xr.GetAttribute("SimilarityId")); continue; } if (xr.Name.CompareTo("PathNode") == 0) { curPathNode = new SortedDictionary <String, Object>(curPath); continue; } if (xr.Name.CompareTo("FileName") == 0 && curPathNode != null) { curPathNode.Add("NodeFileName", xr.ReadElementContentAsString()); continue; } if (xr.Name.CompareTo("Line") == 0 && curPathNode != null && !inSnippet) { curPathNode.Add("NodeLine", xr.ReadElementContentAsString()); continue; } if (xr.Name.CompareTo("Column") == 0 && curPathNode != null) { curPathNode.Add("NodeColumn", xr.ReadElementContentAsString()); continue; } if (xr.Name.CompareTo("NodeId") == 0 && curPathNode != null) { curPathNode.Add("NodeId", xr.ReadElementContentAsString()); continue; } if (xr.Name.CompareTo("Name") == 0 && curPathNode != null) { curPathNode.Add("NodeName", xr.ReadElementContentAsString()); continue; } if (xr.Name.CompareTo("Type") == 0 && curPathNode != null) { curPathNode.Add("NodeType", xr.ReadElementContentAsString()); continue; } if (xr.Name.CompareTo("Length") == 0 && curPathNode != null) { curPathNode.Add("NodeLength", xr.ReadElementContentAsString()); continue; } if (xr.Name.CompareTo("Snippet") == 0 && curPathNode != null) { inSnippet = true; continue; } if (xr.Name.CompareTo("Code") == 0 && curPathNode != null) { curPathNode.Add("NodeCodeSnippet", xr.ReadElementContentAsString()); continue; } } if (xr.NodeType == XmlNodeType.EndElement) { if (xr.Name.CompareTo("CxXMLResults") == 0) { _log.Debug($"[Scan: {scan.ScanId}] Finished processing CxXMLResults"); continue; } if (xr.Name.CompareTo("Query") == 0) { curQueryRec = null; continue; } if (xr.Name.CompareTo("Result") == 0) { curResultRec = null; continue; } if (xr.Name.CompareTo("Path") == 0) { curPath = null; continue; } if (xr.Name.CompareTo("PathNode") == 0) { SastScanDetailOut.write(curPathNode); curPathNode = null; continue; } if (xr.Name.CompareTo("PathNode") == 0) { inSnippet = false; continue; } } } } }
private static void OutputScaScanDetails(ScanDescriptor sd, Transformer inst, Dictionary <string, CxOsaLicenses.License> licenseIndex, Dictionary <string, CxOsaLibraries.Library> libraryIndex) { try { var vulns = CxOsaVulnerabilities.GetVulnerabilities(inst.RestContext, inst.CancelToken, sd.ScanId); var header = new SortedDictionary <String, Object>(); inst.AddPrimaryKeyElements(sd, header); header.Add(PropertyKeys.KEY_SCANFINISH, sd.FinishedStamp); foreach (var vuln in vulns) { var flat = new SortedDictionary <String, Object>(header); flat.Add(PropertyKeys.KEY_SCANID, sd.ScanId); flat.Add("VulnerabilityId", vuln.VulerabilityId); flat.Add(PropertyKeys.KEY_SIMILARITYID, vuln.SimilarityId); flat.Add("CVEName", vuln.CVEName); flat.Add("CVEDescription", vuln.CVEDescription); flat.Add("CVEUrl", vuln.CVEUrl); flat.Add("CVEPubDate", vuln.CVEPublishDate); flat.Add("CVEScore", vuln.CVEScore); flat.Add("Recommendation", vuln.Recommendations); flat.Add(PropertyKeys.KEY_SCANRISKSEV, vuln.Severity.Name); flat.Add("State", vuln.State.StateName); flat.Add("LibraryId", vuln.LibraryId); var lib = libraryIndex[vuln.LibraryId]; if (lib != null) { flat.Add("LibraryName", lib.LibraryName); flat.Add("LibraryVersion", lib.LibraryVersion); flat.Add("LibraryReleaseDate", lib.ReleaseDate); flat.Add("LibraryLatestVersion", lib.LatestVersion); flat.Add("LibraryLatestReleaseDate", lib.LatestVersionReleased); } StringBuilder licenseStr = new StringBuilder(); foreach (var license in lib.Licenses) { if (licenseStr.Length > 0) { licenseStr.Append(";"); } licenseStr.Append(licenseIndex[license].LicenseName); flat.Add($"LibraryLegalRisk_{licenseIndex[license].LicenseName.Replace(" ", "")}", licenseIndex[license].RiskLevel); } flat.Add("LibraryLicenses", licenseStr.ToString()); inst.ScaScanDetailOut.write(flat); } } catch (Exception ex) { _log.Warn($"Could not obtain vulnerability data for scan {sd.ScanId} in project " + $"{sd.Project.ProjectId}: {sd.Project.ProjectName}. Vulnerability data will not be" + $" available.", ex); } }
private void Collector(Type[] types, IServiceCollection collection) { Dictionary <Type, ScanDescriptor> collect = new Dictionary <Type, ScanDescriptor>(types.Length); foreach (var type in types) { var info = type.GetTypeInfo(); if (!info.IsClass) { this.log.LogDebug($"{type.FullName} is not a class. skipping."); continue; } var attr = info.GetCustomAttribute <ServiceAttribute>(); if (attr == null) { continue; } this.log.LogDebug($"Scanning service Type: {type.FullName}"); if (info.IsGenericType && info.IsGenericTypeDefinition) { this.log.LogDebug($"{type.FullName} have no generic arguments and have a just defination. cannot add to service. skipping."); continue; } Type btype = type; //if ServiceAttribute type set, base type will be specified base type. if (attr.BaseType != null && type.IsAssignableFrom(attr.BaseType)) { btype = attr.BaseType; } else //otherwise. start to scan interfaces to determine base type. { //interface scanning default condition: same namespace or same assembly. Type inf = type.GetInterfaces().FirstOrDefault(t => t.Namespace == type.Namespace || t.GetTypeInfo().Assembly.GetName() == info.Assembly.GetName()); this.log.LogDebug($"Scanned base type: {inf?.FullName ?? "(itself)"}"); if (inf != null) { btype = inf; } } if (type != btype) { ScanDescriptor desc; if (!collect.TryGetValue(btype, out desc)) { collect.Add(btype, desc = new ScanDescriptor()); } desc.Types.Add(new Tuple <Type, ServiceAttribute>(type, attr)); } else { this.Register(collection, type, attr.Lifetime, info.GetCustomAttributes <LazyAttribute>().Any()); } } //https://github.com/khellang/Scrutor if (collect.Count > 0) { this.log.LogDebug($"{collect.Count} based Service type will be registered."); ServiceDescriptor desc; foreach (var kv in collect) { if (kv.Value.Types.Count == 0) { continue; } kv.Value.Sort(); List <ServiceDescriptor> results = new List <ServiceDescriptor>(kv.Value.Types.Count); var keyInfo = kv.Key.GetTypeInfo(); var isGen = keyInfo.IsGenericType && keyInfo.IsGenericTypeDefinition; foreach (var tuple in kv.Value.Types) { var valInfo = tuple.Item1.GetTypeInfo(); var item2 = tuple.Item2 as ServiceFlagAttribute; var isLazy = valInfo.GetCustomAttributes <LazyAttribute>().Any(); var rktype = isGen ? kv.Key.MakeGenericType(valInfo.GenericTypeArguments) : kv.Key; this.log.LogDebug($"adding base type: {rktype}"); this.log.LogDebug($"adding body type: {tuple.Item1}"); if (item2 != null) { if (!item2.TryDescribe(rktype, tuple.Item1, results, out desc)) { if (desc != null) { results.Add(this.AddDescription(isLazy ? ServiceUtilities.LazyDescribe(desc) : desc)); } break; } if (desc != null) { results.Add(this.AddDescription(isLazy ? ServiceUtilities.LazyDescribe(desc) : desc)); } } else { results.Add(this.AddDescription(rktype, tuple.Item1, tuple.Item2.Lifetime, isLazy)); } } if (results.Count == 0) { continue; } collection.TryAdd(results[results.Count - 1]); results.RemoveAt(results.Count - 1); if (results.Count == 0) { continue; } this.log.LogDebug($"multiple types from a base type detected. adding {results.Count} type(s) will be registered in {typeof(IEnumerable<>).MakeGenericType(kv.Key)}"); for (int i = 0, len = results.Count; i < len; i++) { results[i] = ServiceDescriptor.Describe(results[i].ImplementationType, results[i].ImplementationType, results[i].Lifetime); } results.Capacity = results.Count; collection.TryAdd(results); collection.TryAddScoped(typeof(IEnumerable <>).MakeGenericType(kv.Key), p => { return(results.Select(d => p.GetService(d.ImplementationType))); }); } } this.log.LogInformation($"${this.scanned.Count} type(s) has been added by ServiceAttribute."); }
private static void AddPrimaryKeyElements(ScanDescriptor rec, IDictionary <string, string> flat) { flat.Add(PropertyKeys.KEY_PROJECTID, rec.Project.ProjectId.ToString()); flat.Add(PropertyKeys.KEY_PROJECTNAME, rec.Project.ProjectName); flat.Add(PropertyKeys.KEY_TEAMNAME, rec.Project.TeamName); }