好的,我有一些主要工作。
首先,一些上下文。我有两个项目,构建两个不同的程序集。在阅读有关如何进行这项工作的各种“解释”时,可能很难理解他们所指的是哪个程序集,所以我将变得迂腐明确。
有很多步骤:
- 将文件添加到库项目中。
- 使其可作为嵌入式资源访问。
- 映射网站中提供嵌入资源文件的端点。
- 将
MyLibrary 是一个包含许多类的类库项目,以及一个 JavaScript 文件,我希望任何引用这些类的网站都可以使用该文件。
在其中我有一个目录“JavaScript”,其中有一个文件“MyJsFile.cs”,我希望客户端可以使用它。
我在 MyLibrary 中安装了 Microsoft.Extensions.FileProviders.Embedded NuGet 包,并将 GenerateEmbeddedFilesManifest 设置为 true。
我已经添加了我希望在 EmbeddedResource ItemGroup 中可用的文件。
所以 MyLibrary.csproj 看起来像:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
</PropertyGroup>
<ItemGroup>
[...]
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="5.0.8" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="JavaScript/MyJsFile.js" />
</ItemGroup>
</Project>
此时,我编译了 MyLibrary,并检查以确认 MyJsFile.js 被列为 MyLibrary.dll 中的嵌入式资源。在 Windows 上,您可以使用 ildasm.exe 检查程序集。如果您在 Linux 上运行,并且不想费心寻找、下载并且可能不得不构建似乎存在的各种竞争版本的 ildasm 之一,您可以将其粘贴到引用的项目中MyLibrary,然后在调试器中跳过它:
var resourceNames = typeof(MyLibrary).Assembly.GetManifestResourceNames();
您应该在 resourceNames 中看到文件的名称。您可以使用以下命令提取整个文件:
using (var resourceStream = typeof(MyLibrary).Assembly.GetManifestResourceStream("MyLibrary.JavaScript.MyJsFile.js"))
{
var rdr = new StreamReader(resourceStream);
var contents = rdr.ReadToEnd();
}
MyWebsite 是一个引用 MyLibrary 的 ASP.NET Core Web 应用程序项目,我需要能够提供该文件。
首先我们需要引用库项目。我的网站.csproj:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
[...]
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../MyLibrary/MyLibrary.csproj" />
</ItemGroup>
</Project>
接下来,我们需要在 Startup.cs 中映射一个端点:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
[...]
app.Map("/mylibrary", builder =>
{
var provider = new ManifestEmbeddedFileProvider(
assembly: Assembly.GetAssembly(typeof(MyLibrary)), "JavaScript");
builder.UseStaticFiles(new StaticFileOptions
{
FileProvider = provider
});
});
}
这样做的目的是设置一个路由规则,以便对以 /mylibrary 开头的文件的任何引用都映射到 MyLibrary.dll 的 JavaScript 目录中的同名嵌入资源
这意味着我们可以在
@section Scripts {
<script src="~/mylibrary/MyJsFile.js"></script>
[...]
}
这是有效的。 MyJsFile.js 中定义的对象在浏览器中可见。
剩下的就是将App.Map("/mylibrary", [...])的配置移动到库中的扩展方法中,这样MyWebsite就不需要知道如何配置的细节了。
为此,我需要向MyLibrary 添加几个 NuGet 包:
- Microsoft.AspNetCore.Mvc.Core
- Microsoft.AspNetCore.StaticFiles
然后我需要在MyLibrary中创建一个扩展方法:
public static class ApplicationBuilderExtensions
{
public static IApplicationBuilder MapMyLibrary(this IApplicationBuilder app, string localPath)
{
app.Map(localPath, builder =>
{
var provider = new ManifestEmbeddedFileProvider(
assembly: Assembly.GetExecutingAssembly(), "JavaScript");
builder.UseStaticFiles(new StaticFileOptions
{
FileProvider = provider
});
});
return app;
}
}
然后,最后,将 MyWebsite 中的 Startup.cs 更改为调用它:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
[...]
app.MapMyLibrary("/mylibrary");
}