| File: ManifestEmbeddedFileProvider.cs | Web Access |
| Project: src\aspnetcore\src\FileProviders\Embedded\src\Microsoft.Extensions.FileProviders.Embedded.csproj (Microsoft.Extensions.FileProviders.Embedded) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection; using Microsoft.AspNetCore.Shared; using Microsoft.Extensions.FileProviders.Embedded.Manifest; using Microsoft.Extensions.Primitives; namespace Microsoft.Extensions.FileProviders; /// <summary> /// An embedded file provider that uses a manifest compiled in the assembly to /// reconstruct the original paths of the embedded files when they were embedded /// into the assembly. /// </summary> public class ManifestEmbeddedFileProvider : IFileProvider { private readonly DateTimeOffset _lastModified; /// <summary> /// Initializes a new instance of <see cref="ManifestEmbeddedFileProvider"/>. /// </summary> /// <param name="assembly">The assembly containing the embedded files.</param> public ManifestEmbeddedFileProvider(Assembly assembly) : this(assembly, ManifestParser.Parse(assembly), ResolveLastModified(assembly)) { } /// <summary> /// Initializes a new instance of <see cref="ManifestEmbeddedFileProvider"/>. /// </summary> /// <param name="assembly">The assembly containing the embedded files.</param> /// <param name="root">The relative path from the root of the manifest to use as root for the provider.</param> public ManifestEmbeddedFileProvider(Assembly assembly, string root) : this(assembly, root, ResolveLastModified(assembly)) { } /// <summary> /// Initializes a new instance of <see cref="ManifestEmbeddedFileProvider"/>. /// </summary> /// <param name="assembly">The assembly containing the embedded files.</param> /// <param name="root">The relative path from the root of the manifest to use as root for the provider.</param> /// <param name="lastModified">The LastModified date to use on the <see cref="IFileInfo"/> instances /// returned by this <see cref="IFileProvider"/>.</param> public ManifestEmbeddedFileProvider(Assembly assembly, string root, DateTimeOffset lastModified) : this(assembly, ManifestParser.Parse(assembly).Scope(root), lastModified) { } /// <summary> /// Initializes a new instance of <see cref="ManifestEmbeddedFileProvider"/>. /// </summary> /// <param name="assembly">The assembly containing the embedded files.</param> /// <param name="root">The relative path from the root of the manifest to use as root for the provider.</param> /// <param name="manifestName">The name of the embedded resource containing the manifest.</param> /// <param name="lastModified">The LastModified date to use on the <see cref="IFileInfo"/> instances /// returned by this <see cref="IFileProvider"/>.</param> public ManifestEmbeddedFileProvider(Assembly assembly, string root, string manifestName, DateTimeOffset lastModified) : this(assembly, ManifestParser.Parse(assembly, manifestName).Scope(root), lastModified) { } internal ManifestEmbeddedFileProvider(Assembly assembly, EmbeddedFilesManifest manifest, DateTimeOffset lastModified) { ArgumentNullThrowHelper.ThrowIfNull(assembly); ArgumentNullThrowHelper.ThrowIfNull(manifest); Assembly = assembly; Manifest = manifest; _lastModified = lastModified; } /// <summary> /// Gets the <see cref="Assembly"/> for this provider. /// </summary> public Assembly Assembly { get; } internal EmbeddedFilesManifest Manifest { get; } /// <inheritdoc /> public IDirectoryContents GetDirectoryContents(string subpath) { var entry = Manifest.ResolveEntry(subpath); if (entry == null || entry == ManifestEntry.UnknownPath) { return NotFoundDirectoryContents.Singleton; } if (!(entry is ManifestDirectory directory)) { return NotFoundDirectoryContents.Singleton; } return new ManifestDirectoryInfo(Assembly, directory, _lastModified); } /// <inheritdoc /> public IFileInfo GetFileInfo(string subpath) { var entry = Manifest.ResolveEntry(subpath); switch (entry) { case null: return new NotFoundFileInfo(subpath); case ManifestFile f: return new ManifestFileInfo(Assembly, f, _lastModified); case ManifestDirectory d when d != ManifestEntry.UnknownPath: return new NotFoundFileInfo(d.Name); } return new NotFoundFileInfo(subpath); } /// <inheritdoc /> public IChangeToken Watch(string filter) { ArgumentNullThrowHelper.ThrowIfNull(filter); return NullChangeToken.Singleton; } [UnconditionalSuppressMessage("SingleFile", "IL3000:Assembly.Location", Justification = "The code handles if the Assembly.Location is empty. Workaround https://github.com/dotnet/runtime/issues/83607")] private static DateTimeOffset ResolveLastModified(Assembly assembly) { var result = DateTimeOffset.UtcNow; var assemblyLocation = assembly.Location; if (!string.IsNullOrEmpty(assemblyLocation)) { try { result = File.GetLastWriteTimeUtc(assemblyLocation); } catch (PathTooLongException) { } catch (UnauthorizedAccessException) { } } return result; } }