/// <summary> /// Creates a reference to a loaded assembly. /// </summary> /// <param name="assembly">Path to the module file.</param> /// <param name="properties">Reference properties (extern aliases, type embedding).</param> /// <param name="documentation">Provides XML documentation for symbol found in the reference.</param> /// <exception cref="ArgumentNullException"><paramref name="assembly"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="properties"/>.<see cref="MetadataReferenceProperties.Kind"/> is not <see cref="MetadataImageKind.Assembly"/>.</exception> /// <exception cref="NotSupportedException"><paramref name="assembly"/> is dynamic, doesn't have a location, or the platform doesn't support reading from the location.</exception> /// <remarks> /// Performance considerations: /// <para> /// It is recommended to use <see cref="AssemblyMetadata.CreateFromFile(string)"/> API when creating multiple references to the same assembly. /// Reusing <see cref="AssemblyMetadata"/> object allows for sharing data accross these references. /// </para> /// </remarks> public static MetadataReference CreateFromAssembly( Assembly assembly, MetadataReferenceProperties properties, DocumentationProvider documentation = null) { // Note: returns MetadataReference and not PortableExecutableReference so that we can in future support assemblies that // which are not backed by PE image. if (assembly == null) { throw new ArgumentNullException(nameof(assembly)); } if (assembly.IsDynamic) { throw new NotSupportedException(CodeAnalysisResources.CantCreateReferenceToDynamicAssembly); } if (properties.Kind != MetadataImageKind.Assembly) { throw new ArgumentException(CodeAnalysisResources.CantCreateModuleReferenceToAssembly, nameof(properties)); } string location = AssemblyLocationLightUp.GetAssemblyLocation(assembly); Stream peStream = FileStreamLightUp.OpenFileStream(location); // The file is locked by the CLR assembly loader, so we can create a lazily read metadata, // which migth also lock the file until the reference is GC'd. var metadata = AssemblyMetadata.CreateFromStream(peStream); return(metadata.GetReference(filePath: location)); }
/// <summary> /// Creates a reference to an assembly or standalone module stored in a file. /// Reads the content of the file into memory. /// </summary> /// <param name="path">Path to the assembly file.</param> /// <param name="properties">Reference properties (extern aliases, type embedding, <see cref="MetadataImageKind"/>).</param> /// <param name="documentation">Provides XML documentation for symbol found in the reference.</param> /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="path"/> is invalid.</exception> /// <exception cref="IOException">An error occurred while reading the file.</exception> /// <remarks> /// Performance considerations: /// <para> /// It is recommended to use <see cref="AssemblyMetadata.CreateFromFile(string)"/> or <see cref="ModuleMetadata.CreateFromFile(string)"/> /// API when creating multiple references to the same file. /// Reusing <see cref="Metadata"/> object allows for sharing data accross these references. /// </para> /// <para> /// The method eagerly reads the entire content of the file into native heap. The native memory block is released /// when the resulting reference becomes unreachable and GC collects it. To decrease memory footprint of the reference and/or manage /// the lifetime deterministically use <see cref="AssemblyMetadata.CreateFromFile(string)"/> /// to create an <see cref="IDisposable"/> metadata object and /// <see cref="AssemblyMetadata.GetReference(DocumentationProvider, ImmutableArray{string}, bool, string, string)"/> /// to get a reference to it. /// </para> /// </remarks> public static PortableExecutableReference CreateFromFile( string path, MetadataReferenceProperties properties = default(MetadataReferenceProperties), DocumentationProvider documentation = null) { var peStream = FileStreamLightUp.OpenFileStream(path); // prefetch image, close stream to avoid locking it: var module = ModuleMetadata.CreateFromStream(peStream, PEStreamOptions.PrefetchEntireImage); if (properties.Kind == MetadataImageKind.Module) { return(module.GetReference(documentation, path)); } // any additional modules constituting the assembly will be read lazily: var assemblyMetadata = AssemblyMetadata.CreateFromFile(module, path); return(assemblyMetadata.GetReference(documentation, properties.Aliases, properties.EmbedInteropTypes, path)); }
/// <summary> /// Creates metadata module from a file containing a portable executable image. /// </summary> /// <param name="path">File path.</param> /// <remarks> /// The file might remain mapped (and read-locked) until this object is disposed. /// The memory map is only created for large files. Small files are read into memory. /// </remarks> /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="path"/> is invalid.</exception> /// <exception cref="IOException">Error opening file <paramref name="path"/>. See <see cref="Exception.InnerException"/> for details.</exception> /// <exception cref="FileNotFoundException">File <paramref name="path"/> not found.</exception> /// <exception cref="NotSupportedException">Reading from a file path is not supported by the platform.</exception> public static ModuleMetadata CreateFromFile(string path) { return(CreateFromStream(FileStreamLightUp.OpenFileStream(path))); }