新文章 网摘 文章 随笔 日记

基于ASP.NET Core的模块化设计: 虚拟文件系统

Abp中文网(https://cn.abp.io/)提供翻译字幕

基于ASP.NET Core的模块化设计: 虚拟文件系统

简介

创建模块化的应用程序很困难. 构建模块化的用户界面更加困难. 需要单独开发模块的页面和组件,但是最后要把它们集成在一起像单个UI一样

创建这样的模块化架构之前需要构建一个强大的基础设施,这就是我们在开源的ABP[1]项目中尝试做的事情

在本文中我会重点介绍虚拟文件系统,它是模块化基础设施的组要组成部分,并解释我们为什么需要它,以及如何在ASP.NET CORE的基础之上开发虚拟文件系统

本文的视频演示请看这里[2]

用户界面组件

典型的ASP.NET CORE MVC Web应用程序UI由静态和动态资源组成

静态资源包括Java,css,image...等文件. 这些资源请求由Static Files中间件响应处理. 它们通常位于程序的wwwroot下

动态资源是Razor视图,页面和组件. 它们由Razor引擎处理,编译和呈现

静态和动态文件通常都位于物理文件系统中(虽然最新的ASP.NET CORE有预编译选项,但要点是相同的)

模块化应用程序中的用户界面组件

在模块化应用程序中, UI组件分散到各个模块中, 通常嵌入到模块程序集中(DLL文件)中

静态文件中间件和Razor视图引擎无法处理分布在模块程序集之间的资源

虚拟文件系统

虚拟文件系统是一个适配器(包装器),使ASP.NET Core可以使用物理文件系统以外的资源

我们的虚拟文件系统实现可以使用三种类型的文件位置

•嵌入式文件: 位于DLL中的文件作为嵌入式资源. 这些资源在应用程序启动时注册到虚拟文件系统•物理文件: 位于web应用程序下的文件(静态资源的wwwroot文件夹,视图的根文件夹,页面..等). 它是向后兼容的•动态文件: 运行时生成的文件(例如动态js/css bundle文件)

动态文件可以覆盖物理文件, 物理文件可以覆盖嵌入文件(如果位于同一路径中). 通过这种方式应用程序可以覆盖模块的UI组件(如CSS文件,JS文件或视图)以便进行自定义

虚拟文件注册

模块应该在应用程序启动时向虚拟文件系统注册/添加自己的嵌入式资源.我们已经为此创建了VirtualFileSystemOptions. 用法示例:

context.Services.Configure<VirtualFileSystemOptions>(options => { options .FileSets .AddEmbedded<MyModule>(); });

上方的代码将MyModule类的程序集中的所有嵌入资源添加到虚拟文件系统(VFS)中,当所有的模块都在VFS中注册后,我们就会在内存中的字典/集合中提供一个文件列表及其路径(嵌入式命名空间转换为路径)

IFileProvider接口

ASP.NET Core使用IFileProvider接口从文件系统中读取文件:

public interface IFileProvider { IFileInfo GetFileInfo(string subpath); IDirectoryContents GetDirectoryContents(string subpath); IChangeToken Watch(string filter); }

•GetFileInfo方法从给定的路径读取文件信息和内容. 如果给定文件不存在,则返回NotFoundFileInfo•GetDirectoryContents方法用于获取目录中的文件和目录列表. 如果给定的目录不存在会返回NotFoundDirectoryContents(可以返回单例实例:NotFoundDirectoryContents.Singleton)•Watch方法用于在给定路径中文件或文件夹发生更改时收到通知. 过滤器可以包含通配符(如'*')

很显然我们应该实现这个接口从嵌入式/动态文件中返回文件,不过我不会在本文中分享实现部分,如果你想了解详细信息,请参阅我们的实现[3]和文档[4]

配置Razor视图引擎

当我们实现了虚拟文件系统,我们就可以配置RazorViewEngineOptions来添加新的自定义文件提供程序:

context.Services.Configure<RazorViewEngineOptions>(options => { options.FileProviders.Insert(0, new MyVirtualFileProvider()); });

替换静态文件中间件

通常我们使用app.UseStaticFiles向浏览器提供物理文件,不过要使用虚拟文件系统,我们需要替换它. 这部分也很简单. 我们可以编写这个一个扩展方法:

public static void UseVirtualFiles(this IApplicationBuilder app) { app.UseStaticFiles( new StaticFileOptions { FileProvider = new MyVirtualFileProvider() } ); }

MyVirtualFileProvider是我们示例的IFileProvider实现. 你可以将FileProvider设置为任何IFileProvider接口的实现类

最后我们使用UseVirtualFiles方法替换UseVirtualFiles:

app.UseVirtualFiles();

写在最后

我试图简单的描述为什么开发模块化的ASP.NET Core Mvc应用程序会需要虚拟文件系统以及如何实现它

我计划根据我的ABP框架[5]开发经验,在ASP.NET Core上发布更多模块化应用程序开发的文章

References

[1] ABP: https://cn.abp.io

[2] 这里: https://www.bilibili.com/video/av47031992?from=search&seid=6709357480596566187

[3] 实现: https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.VirtualFileSystem

[4] 文档: https://cn.abp.io/documents/abp/latest/Virtual-File-System

[5] ABP框架: https://cn.abp.io/

 

https://www.sohu.com/a/304866468_468635

posted @ 2021-03-30 09:21  岭南春  阅读(382)  评论(0)    收藏  举报