• VirtualFileSystem


    物理的文件有wwwroot下文件(JSCSShtml居多),DLL嵌入的资源(json文件居多),Razor文件,

    如何操作这些文件呢,首先先表示这个文件抽象(IFileInfo )

    IFileInfo 表示给定文件提供程序中的某个文件。它是文件一个抽象(名称、物理路径,是否存在,IsDirectory:如果 TryGetDirectoryContents 枚举了子目录,则为 True。 ,返回只读流文件string,bytes),

    其次,提供文件的操作,IFileProvider,得到目录内容(IFileInfo列表,如果有),得到文件IFileInfo,以及监视

    针对以上文件,提供有physicalFileProvider(磁盘)、EmbeddedFileProvider(程序集中)、CompositeFileProvider(IFileProvider 的集合)

    针对这些ABP创建了IVirtualFileProvider,它还是基于CompositeFileProvider进行IFileProvider遍历,因此存在优先级。Dymanic>physical?Embedded

    下面创建CompositeFileProvider,它由下面组成

    dynamicFileProvider:自创建的文件,基于InMemoryFileInfo

    PhysicalFileProvider:物理文件,由配置文件AbpVirtualFileSystemOptions导入,如果PhysicalPath存在

    InternalVirtualFileProvider:嵌入的文件,基于DictionaryBasedFileProvider,由配置文件AbpVirtualFileSystemOptions导入

     protected virtual IFileProvider CreateHybridProvider(IDynamicFileProvider dynamicFileProvider)
            {
                var fileProviders = new List<IFileProvider>();
                fileProviders.Add(dynamicFileProvider);
                if (_options.FileSets.PhysicalPaths.Any())
                {
                    fileProviders.AddRange(
                        _options.FileSets.PhysicalPaths
                            .Select(rootPath => new PhysicalFileProvider(rootPath))
                            .Reverse()
                    );
                }
                fileProviders.Add(new InternalVirtualFileProvider(_options));
                return new CompositeFileProvider(fileProviders);
            }

    回到配置文件AbpVirtualFileSystemOptions的FileSets列表,其使用的拓展方法有

    AddEmbedded:引入Assembly,注意baseNamespace

     list.Add(
                    new EmbeddedFileSet(
                        typeof(T).Assembly,
                        baseNamespace,
                        baseFolderInProject
                    )
                );

     ReplaceEmbeddedByPhysical:

    我们需要的是应用程序在开发时直接使用物理文件的能力, 让浏览器刷新时同步JavaScript文件的任何更改. ReplaceEmbeddedByPhysical 方法使其成为可能.

     分析基于IFileProvider的IVirtualFileProvider实现方法,它的基类型是DictionaryBasedFileProvider,它实现基于IDictionary<string, IFileInfo> Files

    它在Options的Add方法EmbeddedFileSet,调用AddFiles方法,它去除BaseNamespace,目的是填充了IDictionary字典

     foreach (var resourcePath in Assembly.GetManifestResourceNames())
                {
                    
                    if (!BaseNamespace.IsNullOrEmpty() && !resourcePath.StartsWith(BaseNamespace))
                    {
                        continue;
                    }
                    //上面BaseNamespace不为空或与BaseNamespace开头任一条件都执行以下
                    //去掉BaseNamespace.开始部分,split('.')成数组,后两项是文件名,前面是文件夹,join起来成完全的路径
                    var fullPath = ConvertToRelativePath(resourcePath).EnsureStartsWith('/');
                    //如果包括/,说明有目录,则添加目录VirtualDirectoryFileInfo,然后递归,逐层去掉/,直到没有/
                    if (fullPath.Contains("/"))
                    {
                        AddDirectoriesRecursively(files, fullPath.Substring(0, fullPath.LastIndexOf('/')), lastModificationTime);
                    }
                    //添加文件EmbeddedResourceFileInfo
                    files[fullPath] = new EmbeddedResourceFileInfo(
                        Assembly,
                        resourcePath,
                        fullPath,
                        CalculateFileName(fullPath),
                        lastModificationTime
                    );
                }

    GetFileInfo方法,输入不能为空的,则根据字典GetOrDefault(路径),它可以得到文件EmbeddedResourceFileInfo,也可以得到VirtualDirectoryFileInfo

    GetDirectoryContents,它是基于GetFileInfo得到,输入也不能为空的,如果到是文件名,则直接返回没有找到目录,否则遍历字典的File,它去除输入目录,

    找到路径不包含/,注意它可能是文件名,也可能是目录

    foreach (var fileInfo in Files.Values)
                {
                    var fullPath = fileInfo.GetVirtualOrPhysicalPathOrNull();
                    if (!fullPath.StartsWith(directoryPath))
                    {
                        continue;
                    }
    
                    var relativePath = fullPath.Substring(directoryPath.Length);
                    if (relativePath.Contains("/"))
                    {
                        continue;
                    }
    
                    fileList.Add(fileInfo);
                }

    WebContentFileProvider实现

    它是PhysicalFileProvider,以及_virtualFileProvider的复合FileProvider

     protected virtual IFileProvider CreateFileProvider()
            {
                return new CompositeFileProvider(
                    new PhysicalFileProvider(_hostingEnvironment.ContentRootPath),
                    _virtualFileProvider
                );
            }

    1)GetFileInfo方法,要求以/Pages、/Views、/Themes开始,并且,拓展名以.js,.css,.png。.jpg,.jpeg结束等文件

       否则要加上/wwwroot

    2) 同理是GetDirectoryContents,以以/Pages、/Views、/Themes开始

    1、静态资源,使用MiddleWare

     public static IApplicationBuilder UseVirtualFiles(this IApplicationBuilder app)
            {
                return app.UseStaticFiles(
                    new StaticFileOptions
                    {
                        FileProvider = app.ApplicationServices.GetRequiredService<IWebContentFileProvider>()
                    }
                );
            }

    2、RazorEngine

         //Configure Razor
                context.Services.Insert(0,
                    ServiceDescriptor.Singleton<IConfigureOptions<MvcRazorRuntimeCompilationOptions>>(
                        new ConfigureOptions<MvcRazorRuntimeCompilationOptions>(options =>
                            {
                                options.FileProviders.Add(
                                    new RazorViewEngineVirtualFileProvider(
                                        context.Services.GetSingletonInstance<IObjectAccessor<IServiceProvider>>()
                                    )
                                );
                            }
                        )
                    )
                );

    模块内添加嵌入式资源

    1、AbpLocalizationModule下面有AbpValidation
    2、
     Configure<AbpVirtualFileSystemOptions>(options =>
                {
                    options.FileSets.AddEmbedded<AbpAspNetCoreMvcUiBootstrapModule>("Volo.Abp.AspNetCore.Mvc.UI.Bootstrap");
                });
    
      Configure<AbpVirtualFileSystemOptions>(options =>
                {
                    options.FileSets.AddEmbedded<AbpAspNetCoreMvcUiMultiTenancyModule>();
                });
    
        Configure<AbpVirtualFileSystemOptions>(options =>
                {
                    options.FileSets.AddEmbedded<AbpAspNetCoreMvcUiBasicThemeModule>("Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic");
                });
          public override void ConfigureServices(ServiceConfigurationContext context)
            {
                Configure<AbpVirtualFileSystemOptions>(options =>
                {
                    options.FileSets.AddEmbedded<AbpEmailingModule>();
                });       
            }
    
      Configure<AbpVirtualFileSystemOptions>(options =>
                {
                    options.FileSets.AddEmbedded<AbpAspNetCoreMvcUiWidgetsModule>();
                });
    
     Configure<AbpVirtualFileSystemOptions>(options =>
                {
                    options.FileSets.AddEmbedded<AbpLocalizationModule>("Volo.Abp", "Volo/Abp");
                });
    
        Configure<AbpVirtualFileSystemOptions>(options =>
                {
                    options.FileSets.AddEmbedded<AbpUiNavigationModule>();
                });
    
       Configure<AbpVirtualFileSystemOptions>(options =>
                {
                    options.FileSets.AddEmbedded<AbpUiNavigationModule>();
                });
    
      Configure<AbpVirtualFileSystemOptions>(options =>
                {
                    options.FileSets.AddEmbedded<AbpUiModule>();
                });
  • 相关阅读:
    130517Dev GridControl建立多行复杂表头(Banded View)时,统计列与对应列无法对齐的解决办法
    C&C++标准库
    Linux操作系统下的多线程编程详细解析
    Ubuntu12.04用户以root身份登录
    ubuntu永久修改主机名
    linux信号 linux signal
    淘宝api 登录验证
    淘宝开店 防骗 易赛加款诈骗|冲q币恶意差评
    面试..
    test
  • 原文地址:https://www.cnblogs.com/cloudsu/p/11919304.html
Copyright © 2020-2023  润新知