@@ -8,28 +8,34 @@ namespace Microsoft.VisualStudio.TestPlatform.Utilities
88 using System . Collections . ObjectModel ;
99 using System . IO ;
1010 using System . Linq ;
11+ using System . Reflection ;
1112 using System . Threading ;
1213 using System . Threading . Tasks ;
1314
14- using Microsoft . VisualStudio . Coverage . CoreLib . Net ;
1515 using Microsoft . VisualStudio . TestPlatform . ObjectModel ;
1616 using Microsoft . VisualStudio . TestPlatform . ObjectModel . DataCollection ;
1717 using Microsoft . VisualStudio . TestPlatform . ObjectModel . Logging ;
18+ using Microsoft . VisualStudio . TestPlatform . PlatformAbstractions ;
1819
1920 public class CodeCoverageDataAttachmentsHandler : IDataCollectorAttachmentProcessor
2021 {
2122 private const string CoverageUri = "datacollector://microsoft/CodeCoverage/2.0" ;
2223 private const string CoverageFileExtension = ".coverage" ;
2324 private const string CoverageFriendlyName = "Code Coverage" ;
2425
26+ private const string CodeCoverageCoreLibNetAssemblyName = "Microsoft.VisualStudio.Coverage.CoreLib.Net" ;
27+ private const string CoverageFileUtilityTypeName = "CoverageFileUtility" ;
28+ private const string MergeMethodName = "MergeCoverageFilesAsync" ;
29+ private const string WriteMethodName = "WriteCoverageFile" ;
30+
2531 private static readonly Uri CodeCoverageDataCollectorUri = new Uri ( CoverageUri ) ;
2632
2733 public bool SupportsIncrementalProcessing => true ;
2834
2935 public IEnumerable < Uri > GetExtensionUris ( )
3036 {
3137 yield return CodeCoverageDataCollectorUri ;
32- }
38+ }
3339
3440 public async Task < ICollection < AttachmentSet > > ProcessAttachmentSetsAsync ( ICollection < AttachmentSet > attachments , IProgress < int > progressReporter , IMessageLogger logger , CancellationToken cancellationToken )
3541 {
@@ -53,7 +59,7 @@ public async Task<ICollection<AttachmentSet>> ProcessAttachmentSetsAsync(ICollec
5359 }
5460 }
5561
56- if ( coverageReportFilePaths . Count > 1 )
62+ if ( coverageReportFilePaths . Count > 1 )
5763 {
5864 var mergedCoverageReportFilePath = await this . MergeCodeCoverageFilesAsync ( coverageReportFilePaths , progressReporter , cancellationToken ) . ConfigureAwait ( false ) ;
5965 if ( ! string . IsNullOrEmpty ( mergedCoverageReportFilePath ) )
@@ -106,15 +112,25 @@ private async Task<string> MergeCodeCoverageFilesAsync(IList<string> files, IPro
106112
107113 private async Task < string > MergeCodeCoverageFilesAsync ( IList < string > files , CancellationToken cancellationToken )
108114 {
109- var coverageUtility = new CoverageFileUtility ( ) ;
110-
111- var coverageData = await coverageUtility . MergeCoverageFilesAsync (
112- files ,
113- cancellationToken ) . ConfigureAwait ( false ) ;
114-
115- coverageUtility . WriteCoverageFile ( files [ 0 ] , coverageData ) ;
116-
117- foreach ( var file in files . Skip ( 1 ) )
115+ cancellationToken . ThrowIfCancellationRequested ( ) ;
116+
117+ var assemblyPath = Path . Combine ( Path . GetDirectoryName ( typeof ( CodeCoverageDataAttachmentsHandler ) . GetTypeInfo ( ) . Assembly . GetAssemblyLocation ( ) ) , CodeCoverageCoreLibNetAssemblyName + ".dll" ) ;
118+
119+ // Get assembly, type and methods
120+ Assembly assembly = new PlatformAssemblyLoadContext ( ) . LoadAssemblyFromPath ( assemblyPath ) ;
121+ var classType = assembly . GetType ( $ "{ CodeCoverageCoreLibNetAssemblyName } .{ CoverageFileUtilityTypeName } ") ;
122+ var classInstance = Activator . CreateInstance ( classType ) ;
123+ var mergeMethodInfo = classType ? . GetMethod ( MergeMethodName , new [ ] { typeof ( IList < string > ) , typeof ( CancellationToken ) } ) ;
124+ var writeMethodInfo = classType ? . GetMethod ( WriteMethodName ) ;
125+
126+ // Invoke methods
127+ var task = ( Task ) mergeMethodInfo . Invoke ( classInstance , new object [ ] { files , cancellationToken } ) ;
128+ await task . ConfigureAwait ( false ) ;
129+ var coverageData = task . GetType ( ) . GetProperty ( "Result" ) . GetValue ( task , null ) ;
130+ writeMethodInfo . Invoke ( classInstance , new object [ ] { files [ 0 ] , coverageData } ) ;
131+
132+ // Delete original files and keep merged file only
133+ foreach ( var file in files . Skip ( 1 ) )
118134 {
119135 try
120136 {
0 commit comments