using System.Collections.Concurrent;
using System.Text.Json;
namespace Dpz.Core.Web.Library;
public class AssetService
{
private readonly IWebHostEnvironment _environment;
private static readonly ConcurrentDictionary<string, string> Manifest = new(
StringComparer.OrdinalIgnoreCase
);
public AssetService(IWebHostEnvironment environment, ILogger<AssetService> logger)
{
_environment = environment;
if (!Manifest.IsEmpty)
{
return;
}
var manifestPath = Path.Combine(_environment.WebRootPath, "assets-manifest.json");
if (File.Exists(manifestPath))
{
try
{
var json = File.ReadAllText(manifestPath);
var manifest =
JsonSerializer.Deserialize<Dictionary<string, string>>(json)
?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
InitManifest(manifest);
}
catch (Exception ex)
{
logger.LogError(ex, "加载资源清单失败");
}
}
}
private static void InitManifest(Dictionary<string, string> manifest)
{
foreach (var (key, value) in manifest)
{
Manifest.TryAdd(key, value);
}
}
public string GetPath(string path)
{
// 在开发环境中,返回原始路径
if (_environment.IsDevelopment())
{
return path;
}
// 规范化路径键:移除 ~ 和开头的 /
var key = path.TrimStart('~').TrimStart('/');
if (Manifest.TryGetValue(key, out var hashedPath))
{
return "/" + hashedPath;
}
// 如果在清单中未找到,返回原始路径
return path;
}
}
⚠⚠ 以下内容为AI分析的结果,请根据实际情况进行判断。
AssetService 代码解释
这个 AssetService 类是一个用于管理Web应用程序中静态资源(assets)的服务,主要功能是根据环境(开发/生产)返回正确的资源路径。
主要功能
资源清单加载:
- 在构造函数中,从
wwwroot目录加载assets-manifest.json文件 - 这个清单文件应该包含原始资源路径到带哈希版本路径的映射
- 如果加载失败或文件不存在,会初始化一个空字典
- 在构造函数中,从
路径解析:
GetPath方法根据当前环境返回适当的资源路径- 在开发环境(
IsDevelopment())直接返回原始路径 - 在生产环境使用清单文件中的哈希版本路径
工作原理
- 开发环境:直接使用原始路径,方便调试和热重载
- 生产环境:使用带哈希的文件名,实现缓存控制和版本管理
- 路径规范化:处理以
~或/开头的路径,确保能正确匹配清单中的键
典型使用场景
这种服务通常与前端构建工具(如Webpack、Vite等)配合使用,这些工具会生成带哈希的文件名和对应的清单文件,用于解决浏览器缓存问题,同时确保用户能获取到最新的资源版本。
错误处理
- 如果清单文件不存在或解析失败,会记录错误并回退到原始路径
- 如果请求的资源在清单中找不到,同样回退到原始路径
评论加载中...