diff --git a/Volo.Abp.sln b/Volo.Abp.sln index 4f5e933152..eeaf9e984f 100644 --- a/Volo.Abp.sln +++ b/Volo.Abp.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26730.16 +VisualStudioVersion = 15.0.27004.2005 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}" EndProject @@ -150,9 +150,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Abp.Account", "Abp.Account" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Account.Web", "src\Volo.Abp.Account.Web\Volo.Abp.Account.Web.csproj", "{F7DDF25E-58B1-4F68-AEDA-4F2FB4F4467B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Account.Application", "src\Volo.Abp.Account.Application\Volo.Abp.Account.Application.csproj", "{723709F9-09FB-4715-A5D2-DAC8833D8CF7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Account.Application", "src\Volo.Abp.Account.Application\Volo.Abp.Account.Application.csproj", "{723709F9-09FB-4715-A5D2-DAC8833D8CF7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Account.Application.Contracts", "src\Volo.Abp.Account.Application.Contracts\Volo.Abp.Account.Application.Contracts.csproj", "{3E62ED84-8792-4DA6-9B0A-AADEA183C2B3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Account.Application.Contracts", "src\Volo.Abp.Account.Application.Contracts\Volo.Abp.Account.Application.Contracts.csproj", "{3E62ED84-8792-4DA6-9B0A-AADEA183C2B3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.VirtualFileSystem", "src\Volo.Abp.VirtualFileSystem\Volo.Abp.VirtualFileSystem.csproj", "{6E6A7554-3488-45AB-BC0E-9BDE1F19789D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.VirtualFileSystem.Tests", "test\Volo.Abp.VirtualFileSystem.Tests\Volo.Abp.VirtualFileSystem.Tests.csproj", "{F79B6D80-C79B-4C13-9221-CA2345983743}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -392,6 +396,14 @@ Global {3E62ED84-8792-4DA6-9B0A-AADEA183C2B3}.Debug|Any CPU.Build.0 = Debug|Any CPU {3E62ED84-8792-4DA6-9B0A-AADEA183C2B3}.Release|Any CPU.ActiveCfg = Release|Any CPU {3E62ED84-8792-4DA6-9B0A-AADEA183C2B3}.Release|Any CPU.Build.0 = Release|Any CPU + {6E6A7554-3488-45AB-BC0E-9BDE1F19789D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6E6A7554-3488-45AB-BC0E-9BDE1F19789D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6E6A7554-3488-45AB-BC0E-9BDE1F19789D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6E6A7554-3488-45AB-BC0E-9BDE1F19789D}.Release|Any CPU.Build.0 = Release|Any CPU + {F79B6D80-C79B-4C13-9221-CA2345983743}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F79B6D80-C79B-4C13-9221-CA2345983743}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F79B6D80-C79B-4C13-9221-CA2345983743}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F79B6D80-C79B-4C13-9221-CA2345983743}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -465,6 +477,8 @@ Global {F7DDF25E-58B1-4F68-AEDA-4F2FB4F4467B} = {DB012309-74FD-4D5A-B843-DD77BF053BF4} {723709F9-09FB-4715-A5D2-DAC8833D8CF7} = {DB012309-74FD-4D5A-B843-DD77BF053BF4} {3E62ED84-8792-4DA6-9B0A-AADEA183C2B3} = {DB012309-74FD-4D5A-B843-DD77BF053BF4} + {6E6A7554-3488-45AB-BC0E-9BDE1F19789D} = {4C753F64-0C93-4D65-96C2-A40893AFC1E8} + {F79B6D80-C79B-4C13-9221-CA2345983743} = {37087D1B-3693-4E96-983D-A69F210BDE53} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5} diff --git a/src/AbpDesk/AbpDesk.MongoBlog/AbpDesk/Blogging/AbpDeskMongoBlogModule.cs b/src/AbpDesk/AbpDesk.MongoBlog/AbpDesk/Blogging/AbpDeskMongoBlogModule.cs index bbd03a6de5..eeebda22af 100644 --- a/src/AbpDesk/AbpDesk.MongoBlog/AbpDesk/Blogging/AbpDeskMongoBlogModule.cs +++ b/src/AbpDesk/AbpDesk.MongoBlog/AbpDesk/Blogging/AbpDeskMongoBlogModule.cs @@ -1,15 +1,15 @@ using System.Linq; -using System.Reflection; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Volo.Abp; using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.Domain.Repositories; -using Volo.Abp.EmbeddedFiles; using Volo.Abp.Guids; using Volo.Abp.Modularity; using Volo.Abp.MongoDB; using Volo.Abp.Uow; +using Volo.Abp.VirtualFileSystem; +using Volo.Abp.VirtualFileSystem.Embedded; namespace AbpDesk.Blogging { @@ -24,9 +24,9 @@ namespace AbpDesk.Blogging options.WithDefaultRepositories(); }); - services.Configure(options => + services.Configure(options => { - options.Sources.Add( + options.FileSets.Add( new EmbeddedFileSet( "/Areas/", GetType().Assembly, @@ -34,7 +34,7 @@ namespace AbpDesk.Blogging ) ); - options.Sources.Add( + options.FileSets.Add( new EmbeddedFileSet( "/", GetType().Assembly, diff --git a/src/AbpDesk/AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs b/src/AbpDesk/AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs index 50675e6e07..d061904e4c 100644 --- a/src/AbpDesk/AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs +++ b/src/AbpDesk/AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs @@ -3,13 +3,8 @@ using System.Collections.Generic; using System.Globalization; using AbpDesk.EntityFrameworkCore; using AbpDesk.Web.Mvc.Navigation; -using AbpDesk.Web.Mvc.Temp; -using Autofac; -using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Localization; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -40,7 +35,7 @@ namespace AbpDesk.Web.Mvc typeof(AbpAccountWebModule), typeof(AbpAutofacModule) )] - public class AbpDeskWebMvcModule : AbpModule + public class AbpDeskWebMvcModule : AbpModule //TODO: Rename to AbpDeskWebModule, change default namespace to AbpDesk.Web { public override void ConfigureServices(IServiceCollection services) { @@ -60,8 +55,6 @@ namespace AbpDesk.Web.Mvc services.AddAssemblyOf(); - services.GetContainerBuilder().RegisterType(); - services.Configure(options => { options.ScriptBundles.Add("GlobalScripts", new[] @@ -87,7 +80,7 @@ namespace AbpDesk.Web.Mvc } app.UseStaticFiles(); - app.UseEmbeddedFiles(); + app.UseVirtualFiles(); app.UseAuthentication(); diff --git a/src/AbpDesk/AbpDesk.Web.Mvc/Controllers/HomeController.cs b/src/AbpDesk/AbpDesk.Web.Mvc/Controllers/HomeController.cs deleted file mode 100644 index da751428b0..0000000000 --- a/src/AbpDesk/AbpDesk.Web.Mvc/Controllers/HomeController.cs +++ /dev/null @@ -1,14 +0,0 @@ -using AbpDesk.Web.Mvc.Temp; -using Microsoft.AspNetCore.Mvc; -using Volo.Abp.AspNetCore.Mvc; - -namespace AbpDesk.Web.Mvc.Controllers -{ - public class HomeController : AbpController - { - public IActionResult Index(MyClassToTestAutofacCustomRegistration obj) - { - return View(); - } - } -} diff --git a/src/AbpDesk/AbpDesk.Web.Mvc/Pages/Index.cshtml b/src/AbpDesk/AbpDesk.Web.Mvc/Pages/Index.cshtml new file mode 100644 index 0000000000..44ce94ac5a --- /dev/null +++ b/src/AbpDesk/AbpDesk.Web.Mvc/Pages/Index.cshtml @@ -0,0 +1,3 @@ +@page +@model AbpDesk.Web.Mvc.Pages.IndexModel +

Home page!

\ No newline at end of file diff --git a/src/AbpDesk/AbpDesk.Web.Mvc/Pages/Index.cshtml.cs b/src/AbpDesk/AbpDesk.Web.Mvc/Pages/Index.cshtml.cs new file mode 100644 index 0000000000..c289ecbc88 --- /dev/null +++ b/src/AbpDesk/AbpDesk.Web.Mvc/Pages/Index.cshtml.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace AbpDesk.Web.Mvc.Pages +{ + public class IndexModel : PageModel + { + public void OnGet() + { + + } + } +} diff --git a/src/AbpDesk/AbpDesk.Web.Mvc/Pages/_ViewImports.cshtml b/src/AbpDesk/AbpDesk.Web.Mvc/Pages/_ViewImports.cshtml new file mode 100644 index 0000000000..38710b38a2 --- /dev/null +++ b/src/AbpDesk/AbpDesk.Web.Mvc/Pages/_ViewImports.cshtml @@ -0,0 +1,4 @@ +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap +@addTagHelper *, AbpDesk.Web.Mvc \ No newline at end of file diff --git a/src/AbpDesk/AbpDesk.Web.Mvc/Pages/_ViewStart.cshtml b/src/AbpDesk/AbpDesk.Web.Mvc/Pages/_ViewStart.cshtml new file mode 100644 index 0000000000..395aeca572 --- /dev/null +++ b/src/AbpDesk/AbpDesk.Web.Mvc/Pages/_ViewStart.cshtml @@ -0,0 +1,4 @@ +@{ + //TODO: Move this to ~/Pages/Abp/_AppLayout.cshtml..? + Layout = "~/Views/Shared/_AppLayout.cshtml"; +} diff --git a/src/AbpDesk/AbpDesk.Web.Mvc/Temp/MyClassToTestAutofacCustomRegistration.cs b/src/AbpDesk/AbpDesk.Web.Mvc/Temp/MyClassToTestAutofacCustomRegistration.cs deleted file mode 100644 index 2f39953a5a..0000000000 --- a/src/AbpDesk/AbpDesk.Web.Mvc/Temp/MyClassToTestAutofacCustomRegistration.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace AbpDesk.Web.Mvc.Temp -{ - /* Will be removed later */ - public class MyClassToTestAutofacCustomRegistration - { - } -} \ No newline at end of file diff --git a/src/AbpDesk/AbpDesk.Web.Mvc/Views/Home/Index.cshtml b/src/AbpDesk/AbpDesk.Web.Mvc/Views/Home/Index.cshtml deleted file mode 100644 index da227c3648..0000000000 --- a/src/AbpDesk/AbpDesk.Web.Mvc/Views/Home/Index.cshtml +++ /dev/null @@ -1 +0,0 @@ -

Home

\ No newline at end of file diff --git a/src/AbpDesk/Web_PlugIns/AbpDesk.MongoBlog.dll b/src/AbpDesk/Web_PlugIns/AbpDesk.MongoBlog.dll index 629eb6cda8..ae3224578d 100644 Binary files a/src/AbpDesk/Web_PlugIns/AbpDesk.MongoBlog.dll and b/src/AbpDesk/Web_PlugIns/AbpDesk.MongoBlog.dll differ diff --git a/src/Volo.Abp.Account.Web/AbpAccountWebModule.cs b/src/Volo.Abp.Account.Web/AbpAccountWebModule.cs index 39bed90383..edd2390af9 100644 --- a/src/Volo.Abp.Account.Web/AbpAccountWebModule.cs +++ b/src/Volo.Abp.Account.Web/AbpAccountWebModule.cs @@ -1,9 +1,10 @@ using System.Reflection; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap; -using Volo.Abp.EmbeddedFiles; using Volo.Abp.Identity; using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; +using Volo.Abp.VirtualFileSystem.Embedded; namespace Volo.Abp.Account.Web { @@ -16,9 +17,9 @@ namespace Volo.Abp.Account.Web { services.AddAssemblyOf(); - services.Configure(options => + services.Configure(options => { - options.Sources.Add( + options.FileSets.Add( new EmbeddedFileSet( "/Areas/", GetType().GetTypeInfo().Assembly, @@ -26,7 +27,7 @@ namespace Volo.Abp.Account.Web ) ); - options.Sources.Add( + options.FileSets.Add( new EmbeddedFileSet( "/", GetType().GetTypeInfo().Assembly, diff --git a/src/Volo.Abp.AspNetCore.EmbeddedFiles/Microsoft/AspNetCore/Builder/EmbeddedFilesApplicationBuilderExtensions.cs b/src/Volo.Abp.AspNetCore.EmbeddedFiles/Microsoft/AspNetCore/Builder/VirtualFileSystemApplicationBuilderExtensions.cs similarity index 59% rename from src/Volo.Abp.AspNetCore.EmbeddedFiles/Microsoft/AspNetCore/Builder/EmbeddedFilesApplicationBuilderExtensions.cs rename to src/Volo.Abp.AspNetCore.EmbeddedFiles/Microsoft/AspNetCore/Builder/VirtualFileSystemApplicationBuilderExtensions.cs index b13e0b3c5a..e35328afd8 100644 --- a/src/Volo.Abp.AspNetCore.EmbeddedFiles/Microsoft/AspNetCore/Builder/EmbeddedFilesApplicationBuilderExtensions.cs +++ b/src/Volo.Abp.AspNetCore.EmbeddedFiles/Microsoft/AspNetCore/Builder/VirtualFileSystemApplicationBuilderExtensions.cs @@ -1,16 +1,17 @@ using Volo.Abp.AspNetCore.EmbeddedFiles; +using Volo.Abp.AspNetCore.VirtualFileSystem; namespace Microsoft.AspNetCore.Builder { - public static class EmbeddedFilesApplicationBuilderExtensions + public static class VirtualFileSystemApplicationBuilderExtensions { - public static void UseEmbeddedFiles(this IApplicationBuilder app) + public static void UseVirtualFiles(this IApplicationBuilder app) { //TODO: Can improve it or create a custom middleware? app.UseStaticFiles( new StaticFileOptions { - FileProvider = new EmbeddedResourceFileProvider( + FileProvider = new AspNetCoreVirtualFileProvider( app.ApplicationServices ) } diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/AbpAspNetCoreMvcUiBootstrapModule.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/AbpAspNetCoreMvcUiBootstrapModule.cs index 6a04880e42..a460915b82 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/AbpAspNetCoreMvcUiBootstrapModule.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/AbpAspNetCoreMvcUiBootstrapModule.cs @@ -2,8 +2,9 @@ using System.Reflection; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Mvc.Bundling; -using Volo.Abp.EmbeddedFiles; using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; +using Volo.Abp.VirtualFileSystem.Embedded; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap { @@ -14,9 +15,9 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap { services.AddAssemblyOf(); - services.Configure(options => + services.Configure(options => { - options.Sources.Add( + options.FileSets.Add( new EmbeddedFileSet( "/", GetType().GetTypeInfo().Assembly, @@ -24,7 +25,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap ) ); - options.Sources.Add( + options.FileSets.Add( new EmbeddedFileSet( "/Views/", GetType().GetTypeInfo().Assembly, @@ -47,7 +48,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap "/libs/jquery/jquery-3.1.1.min.js", "/libs/tether/js/tether.min.js", "/libs/bootstrap/js/bootstrap.min.js", - "/libs/abp/abp.jquery.js?_v" + DateTime.Now.Ticks //TODO: Move this to Volo.Abp.AspNetCore.Mvc.UI.. or to new jQuery package? + "/libs/abp/abp-jquery.js?_v" + DateTime.Now.Ticks //TODO: Move this to Volo.Abp.AspNetCore.Mvc.UI.. or to new jQuery package? }); }); } diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI/AbpAspNetCoreMvcUiModule.cs b/src/Volo.Abp.AspNetCore.Mvc.UI/AbpAspNetCoreMvcUiModule.cs index 41edda0d20..7e342cfee2 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI/AbpAspNetCoreMvcUiModule.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI/AbpAspNetCoreMvcUiModule.cs @@ -2,8 +2,9 @@ using System.Reflection; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Mvc.Bundling; -using Volo.Abp.EmbeddedFiles; using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; +using Volo.Abp.VirtualFileSystem.Embedded; namespace Volo.Abp.AspNetCore.Mvc { @@ -14,9 +15,9 @@ namespace Volo.Abp.AspNetCore.Mvc { services.AddAssemblyOf(); - services.Configure(options => + services.Configure(options => { - options.Sources.Add( + options.FileSets.Add( new EmbeddedFileSet( "/Views/", GetType().GetTypeInfo().Assembly, @@ -24,7 +25,7 @@ namespace Volo.Abp.AspNetCore.Mvc ) ); - options.Sources.Add( + options.FileSets.Add( new EmbeddedFileSet( "/", GetType().GetTypeInfo().Assembly, diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj b/src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj index f7b935777e..9b311b1d31 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj +++ b/src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj @@ -19,12 +19,11 @@ - - + diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI/wwwroot/libs/abp/abp.jquery.js b/src/Volo.Abp.AspNetCore.Mvc.UI/wwwroot/libs/abp/abp-jquery.js similarity index 100% rename from src/Volo.Abp.AspNetCore.Mvc.UI/wwwroot/libs/abp/abp.jquery.js rename to src/Volo.Abp.AspNetCore.Mvc.UI/wwwroot/libs/abp/abp-jquery.js diff --git a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs index 3f8f3ef284..9b5d38ba79 100644 --- a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs +++ b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs @@ -7,7 +7,6 @@ using Microsoft.AspNetCore.Mvc.ApplicationParts; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -using Volo.Abp.AspNetCore.EmbeddedFiles; using Volo.Abp.DependencyInjection; using Volo.Abp.Modularity; using Microsoft.AspNetCore.Mvc; @@ -17,6 +16,7 @@ using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.ViewComponents; using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp.AspNetCore.Mvc.Conventions; +using Volo.Abp.AspNetCore.Mvc.VirtualFileSystem; using Volo.Abp.Http; using Volo.Abp.Http.Modeling; @@ -34,7 +34,7 @@ namespace Volo.Abp.AspNetCore.Mvc new ConfigureOptions(options => { options.FileProviders.Add( - new EmbeddedResourceViewFileProvider( + new AspNetCoreVirtualViewFileProvider( services.GetSingletonInstance>() ) ); diff --git a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/VirtualFileSystem/AspNetCoreVirtualViewFileProvider.cs b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/VirtualFileSystem/AspNetCoreVirtualViewFileProvider.cs new file mode 100644 index 0000000000..f8982ce5a5 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/VirtualFileSystem/AspNetCoreVirtualViewFileProvider.cs @@ -0,0 +1,15 @@ +using System; +using Volo.Abp.AspNetCore.VirtualFileSystem; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Mvc.VirtualFileSystem +{ + //TODO: Move to Volo.Abp.AspNetCore.Mvc project! + public class AspNetCoreVirtualViewFileProvider : AspNetCoreVirtualFileProvider + { + public AspNetCoreVirtualViewFileProvider(IObjectAccessor serviceProviderAccessor) + : base(serviceProviderAccessor) + { + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj b/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj index 4a835450bf..ecd09c41c1 100644 --- a/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj +++ b/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj @@ -14,7 +14,7 @@ - + diff --git a/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs b/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs index f6df6760c2..24039ffbbe 100644 --- a/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs +++ b/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs @@ -3,9 +3,11 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.AspNetCore { + [DependsOn(typeof(AbpVirtualFileSystemModule))] public class AbpAspNetCoreModule : IAbpModule { public void ConfigureServices(IServiceCollection services) diff --git a/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/EmbeddedFiles/EmbeddedResourceItemFileInfo.cs b/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/EmbeddedFiles/EmbeddedResourceItemFileInfo.cs deleted file mode 100644 index a4faf6dd79..0000000000 --- a/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/EmbeddedFiles/EmbeddedResourceItemFileInfo.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.IO; -using Microsoft.Extensions.FileProviders; -using Volo.Abp.EmbeddedFiles; - -namespace Volo.Abp.AspNetCore.EmbeddedFiles -{ - public class EmbeddedResourceItemFileInfo : IFileInfo - { - public bool Exists => true; - - public long Length => _fileInfo.Content.Length; - - public string PhysicalPath => null; - - public string Name => _fileInfo.FileName; - - public DateTimeOffset LastModified => _fileInfo.LastModifiedUtc; - - public bool IsDirectory => false; - - private readonly EmbeddedFileInfo _fileInfo; - - public EmbeddedResourceItemFileInfo(EmbeddedFileInfo fileInfo) - { - _fileInfo = fileInfo; - } - - public Stream CreateReadStream() - { - return new MemoryStream(_fileInfo.Content); - } - } -} \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/EmbeddedFiles/EmbeddedResourceViewFileProvider.cs b/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/EmbeddedFiles/EmbeddedResourceViewFileProvider.cs deleted file mode 100644 index 61319b0843..0000000000 --- a/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/EmbeddedFiles/EmbeddedResourceViewFileProvider.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using Volo.Abp.DependencyInjection; -using Volo.Abp.EmbeddedFiles; - -namespace Volo.Abp.AspNetCore.EmbeddedFiles -{ - //TODO: Remove to Volo.Abp.AspNetCore.Mvc project! - public class EmbeddedResourceViewFileProvider : EmbeddedResourceFileProvider - { - public EmbeddedResourceViewFileProvider(IObjectAccessor serviceProviderAccessor) - : base(serviceProviderAccessor) - { - } - - protected override bool IsIgnoredFile(EmbeddedFileInfo resource) - { - return resource.FileExtension != "cshtml"; - } - } -} \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/EmbeddedFiles/AspNetCoreEmbeddedFileOptions.cs b/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/AspNetCoreVirtualFileOptions.cs similarity index 50% rename from src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/EmbeddedFiles/AspNetCoreEmbeddedFileOptions.cs rename to src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/AspNetCoreVirtualFileOptions.cs index 2977a419b3..57395163eb 100644 --- a/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/EmbeddedFiles/AspNetCoreEmbeddedFileOptions.cs +++ b/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/AspNetCoreVirtualFileOptions.cs @@ -1,17 +1,17 @@ using System.Collections.Generic; -namespace Volo.Abp.AspNetCore.EmbeddedFiles +namespace Volo.Abp.AspNetCore.VirtualFileSystem { - internal class AspNetCoreEmbeddedFileOptions + internal class AspNetCoreVirtualFileOptions //TODO: and use this! { public HashSet IgnoredFileExtensions { get; } - public AspNetCoreEmbeddedFileOptions() + public AspNetCoreVirtualFileOptions() { IgnoredFileExtensions = new HashSet { - "cshtml", - "config" + ".cshtml", + ".config" }; } } diff --git a/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/EmbeddedFiles/EmbeddedResourceFileProvider.cs b/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/AspNetCoreVirtualFileProvider.cs similarity index 50% rename from src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/EmbeddedFiles/EmbeddedResourceFileProvider.cs rename to src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/AspNetCoreVirtualFileProvider.cs index c59873d1e3..1643a4d796 100644 --- a/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/EmbeddedFiles/EmbeddedResourceFileProvider.cs +++ b/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/AspNetCoreVirtualFileProvider.cs @@ -4,74 +4,69 @@ using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Options; using Microsoft.Extensions.Primitives; using Volo.Abp.DependencyInjection; -using Volo.Abp.EmbeddedFiles; +using Volo.Abp.VirtualFileSystem; -namespace Volo.Abp.AspNetCore.EmbeddedFiles +namespace Volo.Abp.AspNetCore.VirtualFileSystem { - public class EmbeddedResourceFileProvider : IFileProvider + public class AspNetCoreVirtualFileProvider : IFileProvider { - private readonly Lazy _embeddedResourceManager; - private readonly Lazy _options; + private readonly Lazy _embeddedResourceManager; + private readonly Lazy _options; private readonly IObjectAccessor _serviceProviderAccessor; - public EmbeddedResourceFileProvider(IServiceProvider serviceProvider) + public AspNetCoreVirtualFileProvider(IServiceProvider serviceProvider) : this(new ObjectAccessor(serviceProvider)) { - + } - public EmbeddedResourceFileProvider(IObjectAccessor serviceProviderAccessor) + public AspNetCoreVirtualFileProvider(IObjectAccessor serviceProviderAccessor) { _serviceProviderAccessor = serviceProviderAccessor; - _embeddedResourceManager = new Lazy( - () => serviceProviderAccessor.Value.GetRequiredService(), + _embeddedResourceManager = new Lazy( + () => serviceProviderAccessor.Value.GetRequiredService(), true ); - _options = new Lazy( - () => serviceProviderAccessor.Value.GetRequiredService>().Value, + _options = new Lazy( + () => serviceProviderAccessor.Value.GetRequiredService>().Value, true ); } public IFileInfo GetFileInfo(string subpath) { - if (!IsInitialized()) - { - return new NotFoundFileInfo(subpath); - } - - var resource = _embeddedResourceManager.Value.FindFile(subpath); + //TODO: Ignore files in _options.Value.IgnoredFileExtensions - if (resource == null || IsIgnoredFile(resource)) + if (!IsInitialized()) { return new NotFoundFileInfo(subpath); } - return new EmbeddedResourceItemFileInfo(resource); + return _embeddedResourceManager.Value.GetFileInfo(subpath); } public IDirectoryContents GetDirectoryContents(string subpath) { + //TODO: Ignore files in _options.Value.IgnoredFileExtensions + if (!IsInitialized()) { return new NotFoundDirectoryContents(); } - //TODO: Implement...? - - return new NotFoundDirectoryContents(); + return _embeddedResourceManager.Value.GetDirectoryContents(subpath); } public IChangeToken Watch(string filter) { - return NullChangeToken.Singleton; - } + if (!IsInitialized()) + { + return NullChangeToken.Singleton; + } - protected virtual bool IsIgnoredFile(EmbeddedFileInfo resource) - { - return resource.FileExtension != null && _options.Value.IgnoredFileExtensions.Contains(resource.FileExtension); + return _embeddedResourceManager.Value.Watch(filter); } private bool IsInitialized() diff --git a/src/Volo.Abp.Identity.Web/AbpIdentityWebModule.cs b/src/Volo.Abp.Identity.Web/AbpIdentityWebModule.cs index ddc7a29b57..552bc50f60 100644 --- a/src/Volo.Abp.Identity.Web/AbpIdentityWebModule.cs +++ b/src/Volo.Abp.Identity.Web/AbpIdentityWebModule.cs @@ -1,12 +1,12 @@ -using System.Reflection; -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap; -using Volo.Abp.EmbeddedFiles; using Volo.Abp.Identity.Web.Areas.Identity.Localization.Resource; using Volo.Abp.Identity.Web.Navigation; using Volo.Abp.Localization; using Volo.Abp.Modularity; using Volo.Abp.Ui.Navigation; +using Volo.Abp.VirtualFileSystem; +using Volo.Abp.VirtualFileSystem.Embedded; namespace Volo.Abp.Identity.Web { @@ -23,20 +23,28 @@ namespace Volo.Abp.Identity.Web options.MenuContributors.Add(new AbpIdentityWebMainMenuContributor()); }); - services.Configure(options => + services.Configure(options => { - options.Sources.Add( + options.FileSets.Add( + new EmbeddedFileSet( + "/Pages/", + GetType().Assembly, + "Volo.Abp.Identity.Web.Pages" + ) + ); + + options.FileSets.Add( new EmbeddedFileSet( "/Areas/", - GetType().GetTypeInfo().Assembly, + GetType().Assembly, "Volo.Abp.Identity.Web.Areas" ) ); - options.Sources.Add( + options.FileSets.Add( new EmbeddedFileSet( "/", - GetType().GetTypeInfo().Assembly, + GetType().Assembly, "Volo.Abp.Identity.Web.wwwroot" ) ); diff --git a/src/Volo.Abp.Identity.Web/Areas/Identity/Controllers/UsersController.cs b/src/Volo.Abp.Identity.Web/Areas/Identity/Controllers/UsersController.cs index 15437c706b..3f10c8bc59 100644 --- a/src/Volo.Abp.Identity.Web/Areas/Identity/Controllers/UsersController.cs +++ b/src/Volo.Abp.Identity.Web/Areas/Identity/Controllers/UsersController.cs @@ -22,10 +22,10 @@ namespace Volo.Abp.Identity.Web.Areas.Identity.Controllers _identityRoleAppService = identityRoleAppService; } - public async Task Index() - { - return View(); - } + //public async Task Index() + //{ + // return View(); + //} public async Task Create() { diff --git a/src/Volo.Abp.Identity.Web/Pages/Identity/Users/Index.cshtml b/src/Volo.Abp.Identity.Web/Pages/Identity/Users/Index.cshtml new file mode 100644 index 0000000000..166e249849 --- /dev/null +++ b/src/Volo.Abp.Identity.Web/Pages/Identity/Users/Index.cshtml @@ -0,0 +1,48 @@ +@page +@model Volo.Abp.Identity.Web.Pages.Identity.Users.IndexModel +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.Identity.Web.Areas.Identity.Localization.Resource +@inject IHtmlLocalizer L +@section styles { + + + +} + +@section scripts { + + + +} + +
+
+

@L["Users"]

+
+
+ + +
+
+ + + + + + + + + + +
@L["Actions"]@L["UserName"]@L["EmailAddress"]@L["PhoneNumber"]
+ + + \ No newline at end of file diff --git a/src/Volo.Abp.Identity.Web/Pages/Identity/Users/Index.cshtml.cs b/src/Volo.Abp.Identity.Web/Pages/Identity/Users/Index.cshtml.cs new file mode 100644 index 0000000000..1557445d6b --- /dev/null +++ b/src/Volo.Abp.Identity.Web/Pages/Identity/Users/Index.cshtml.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace Volo.Abp.Identity.Web.Pages.Identity.Users +{ + public class IndexModel : PageModel + { + public void OnGet() + { + + } + } +} diff --git a/src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.csproj b/src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.csproj index 77797d9147..3b412c01b5 100644 --- a/src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.csproj +++ b/src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.csproj @@ -17,6 +17,10 @@
+ + + + diff --git a/src/Volo.Abp.VirtualFileSystem/Volo.Abp.VirtualFileSystem.csproj b/src/Volo.Abp.VirtualFileSystem/Volo.Abp.VirtualFileSystem.csproj new file mode 100644 index 0000000000..8c77bb369e --- /dev/null +++ b/src/Volo.Abp.VirtualFileSystem/Volo.Abp.VirtualFileSystem.csproj @@ -0,0 +1,24 @@ + + + + + + netstandard2.0 + Volo.Abp.VirtualFileSystem + Volo.Abp.VirtualFileSystem + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + false + false + false + + + + + + + + + + + + diff --git a/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/AbpVirtualFileSystemModule.cs b/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/AbpVirtualFileSystemModule.cs new file mode 100644 index 0000000000..cef8ab811e --- /dev/null +++ b/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/AbpVirtualFileSystemModule.cs @@ -0,0 +1,13 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; + +namespace Volo.Abp.VirtualFileSystem +{ + public class AbpVirtualFileSystemModule : AbpModule + { + public override void ConfigureServices(IServiceCollection services) + { + services.AddAssemblyOf(); + } + } +} diff --git a/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/EmbeddedFileSet.cs b/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/EmbeddedFileSet.cs new file mode 100644 index 0000000000..e4e638e125 --- /dev/null +++ b/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/EmbeddedFileSet.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using Microsoft.Extensions.FileProviders; + +namespace Volo.Abp.VirtualFileSystem.Embedded +{ + public class EmbeddedFileSet : IVirtualFileSet + { + public string RootPath { get; } + + public Assembly Assembly { get; } + + public string ResourceNamespace { get; } + + public EmbeddedFileSet(string rootPath, Assembly assembly, string resourceNamespace) + { + RootPath = rootPath.EnsureEndsWith('/'); + Assembly = assembly; + ResourceNamespace = resourceNamespace; + } + + public void AddFiles(Dictionary files) + { + var lastModificationTime = GetLastModificationTime(); + + foreach (var resourcePath in Assembly.GetManifestResourceNames()) + { + if (!resourcePath.StartsWith(ResourceNamespace)) + { + continue; + } + + var fullPath = RootPath + ConvertToRelativePath(resourcePath); + + if (fullPath.Contains("/")) + { + AddDirectoriesRecursively(files, fullPath.Substring(0, fullPath.LastIndexOf('/')), lastModificationTime); + } + + files[fullPath] = new EmbeddedResourceFileInfo( + Assembly, + resourcePath, + fullPath, + CalculateFileName(fullPath), + lastModificationTime, + false + ); + } + } + + private void AddDirectoriesRecursively(Dictionary files, string directoryPath, DateTimeOffset lastModificationTime) + { + if (files.ContainsKey(directoryPath)) + { + return; + } + + files[directoryPath] = new EmbeddedResourceFileInfo( //TODO: Create a different simpler class! + Assembly, + null, + directoryPath, + CalculateFileName(directoryPath), + lastModificationTime, + true + ); + + if (directoryPath.Contains("/")) + { + AddDirectoriesRecursively(files, directoryPath.Substring(0, directoryPath.LastIndexOf('/')), lastModificationTime); + } + } + + private DateTimeOffset GetLastModificationTime() + { + var lastModified = DateTimeOffset.UtcNow; + + if (!string.IsNullOrEmpty(Assembly.Location)) + { + try + { + lastModified = File.GetLastWriteTimeUtc(Assembly.Location); + } + catch (PathTooLongException) + { + } + catch (UnauthorizedAccessException) + { + } + } + + return lastModified; + } + + private string ConvertToRelativePath(string resourceName) + { + resourceName = resourceName.Substring(ResourceNamespace.Length + 1); + + var pathParts = resourceName.Split('.'); + if (pathParts.Length <= 2) + { + return resourceName; + } + + var folder = pathParts.Take(pathParts.Length - 2).Select(NormalizeFolderName).JoinAsString("/"); + var fileName = pathParts[pathParts.Length - 2] + "." + pathParts[pathParts.Length - 1]; + + return folder + "/" + fileName; + } + + private static string NormalizeFolderName(string pathPart) + { + //TODO: Implement all rules of .NET + return pathPart.Replace('-', '_'); + } + + private static string CalculateFileName(string filePath) + { + if (!filePath.Contains("/")) + { + return filePath; + } + + return filePath.Substring(filePath.LastIndexOf("/", StringComparison.Ordinal) + 1); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/EmbeddedResourceFileInfo.cs b/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/EmbeddedResourceFileInfo.cs new file mode 100644 index 0000000000..008912c48e --- /dev/null +++ b/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/EmbeddedResourceFileInfo.cs @@ -0,0 +1,90 @@ +using System; +using System.IO; +using System.Reflection; +using Microsoft.Extensions.FileProviders; + +namespace Volo.Abp.VirtualFileSystem.Embedded +{ + /// + /// Represents a file embedded in an assembly. + /// + public class EmbeddedResourceFileInfo : IFileInfo + { + public bool Exists => true; + + public long Length + { + get + { + if (!_length.HasValue) + { + using (var stream = _assembly.GetManifestResourceStream(_resourcePath)) + { + _length = stream.Length; + } + } + + return _length.Value; + } + } + private long? _length; + + public string PhysicalPath { get; } + + public string Name { get; } + + public ManifestResourceInfo ManifestResourceInfo { get; } + + /// + /// The time, in UTC. + /// + public DateTimeOffset LastModified { get; } + + public bool IsDirectory { get; } + + private readonly Assembly _assembly; + private readonly string _resourcePath; + + public EmbeddedResourceFileInfo( + Assembly assembly, + string resourcePath, + string physicalPath, + string name, + DateTimeOffset lastModified, + bool isDirectory) + { + _assembly = assembly; + _resourcePath = resourcePath; + + PhysicalPath = physicalPath; + Name = name; + + if (_resourcePath != null) + { + ManifestResourceInfo = _assembly.GetManifestResourceInfo(_resourcePath); + } + + LastModified = lastModified; + IsDirectory = isDirectory; + } + + /// + public Stream CreateReadStream() + { + + var stream = _assembly.GetManifestResourceStream(_resourcePath); + + if (!_length.HasValue) + { + _length = stream.Length; + } + + return stream; + } + + public override string ToString() + { + return $"[EmbeddedResourceFileInfo] {Name} ({PhysicalPath})"; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFilePathHelper.cs b/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/EmbeddedFilePathHelper.cs similarity index 91% rename from src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFilePathHelper.cs rename to src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/EmbeddedFilePathHelper.cs index e50cf12d65..0803d9a321 100644 --- a/src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFilePathHelper.cs +++ b/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/EmbeddedFilePathHelper.cs @@ -1,8 +1,8 @@ using System; -namespace Volo.Abp.EmbeddedFiles +namespace Volo.Abp.VirtualFileSystem { - public static class EmbeddedFilePathHelper + internal static class VirtualFilePathHelper { public static string NormalizePath(string fullPath) { diff --git a/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/EnumerableDirectoryContents.cs b/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/EnumerableDirectoryContents.cs new file mode 100644 index 0000000000..a80b638680 --- /dev/null +++ b/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/EnumerableDirectoryContents.cs @@ -0,0 +1,31 @@ +using System.Collections; +using System.Collections.Generic; +using JetBrains.Annotations; +using Microsoft.Extensions.FileProviders; + +namespace Volo.Abp.VirtualFileSystem +{ + internal class EnumerableDirectoryContents : IDirectoryContents + { + private readonly IEnumerable _entries; + + public EnumerableDirectoryContents([NotNull] IEnumerable entries) + { + Check.NotNull(entries, nameof(entries)); + + _entries = entries; + } + + public bool Exists => true; + + public IEnumerator GetEnumerator() + { + return _entries.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _entries.GetEnumerator(); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/IEmbeddedFileManager.cs b/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/IEmbeddedFileManager.cs new file mode 100644 index 0000000000..a8f52bbf10 --- /dev/null +++ b/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/IEmbeddedFileManager.cs @@ -0,0 +1,8 @@ +using Microsoft.Extensions.FileProviders; + +namespace Volo.Abp.VirtualFileSystem +{ + public interface IVirtualFileProvider : IFileProvider + { + } +} \ No newline at end of file diff --git a/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/IVirtualFileSet.cs b/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/IVirtualFileSet.cs new file mode 100644 index 0000000000..1880165d02 --- /dev/null +++ b/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/IVirtualFileSet.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using Microsoft.Extensions.FileProviders; + +namespace Volo.Abp.VirtualFileSystem +{ + public interface IVirtualFileSet + { + void AddFiles(Dictionary files); + } +} \ No newline at end of file diff --git a/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileProvider.cs b/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileProvider.cs new file mode 100644 index 0000000000..3972850045 --- /dev/null +++ b/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileProvider.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Options; +using Microsoft.Extensions.Primitives; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.VirtualFileSystem +{ + public class VirtualFileProvider : IVirtualFileProvider, ISingletonDependency + { + private readonly VirtualFileSystemOptions _options; + private readonly Lazy> _files; + + public VirtualFileProvider(IOptions options) + { + _options = options.Value; + _files = new Lazy>( + CreateResourcesDictionary, + true + ); + } + + public IFileInfo GetFileInfo(string subpath) + { + if (string.IsNullOrEmpty(subpath)) + { + return new NotFoundFileInfo(subpath); + } + + var file = _files.Value.GetOrDefault(VirtualFilePathHelper.NormalizePath(subpath)); + + if (file == null) + { + return new NotFoundFileInfo(subpath); + } + + return file; + } + + public IDirectoryContents GetDirectoryContents(string subpath) + { + var directory = GetFileInfo(subpath); + if (!directory.IsDirectory) + { + return new NotFoundDirectoryContents(); + } + + var fileList = new List(); + + var directoryPath = subpath + "/"; + foreach (var fileInfo in _files.Value.Values) + { + if (!fileInfo.PhysicalPath.StartsWith(directoryPath)) + { + continue; + } + + var relativePath = fileInfo.PhysicalPath.Substring(directoryPath.Length); + if (relativePath.Contains("/")) + { + continue; + } + + fileList.Add(fileInfo); + } + + return new EnumerableDirectoryContents(fileList); + } + + public IChangeToken Watch(string filter) + { + return NullChangeToken.Singleton; + } + + private Dictionary CreateResourcesDictionary() + { + var files = new Dictionary(StringComparer.OrdinalIgnoreCase); + + foreach (var set in _options.FileSets) + { + set.AddFiles(files); + } + + return files; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileSystemOptions.cs b/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileSystemOptions.cs new file mode 100644 index 0000000000..087f10af53 --- /dev/null +++ b/src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileSystemOptions.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace Volo.Abp.VirtualFileSystem +{ + public class VirtualFileSystemOptions + { + public List FileSets { get; } + + public VirtualFileSystemOptions() + { + FileSets = new List(); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileInfo.cs b/src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileInfo.cs deleted file mode 100644 index 8720829104..0000000000 --- a/src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileInfo.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.IO; -using System.Reflection; -using JetBrains.Annotations; - -namespace Volo.Abp.EmbeddedFiles -{ - /// - /// Stores needed information of an embedded resource. - /// - public class EmbeddedFileInfo - { - /// - /// File name including extension. - /// - [NotNull] - public string FileName { get; } - - /// - /// File extension (without dot) if available. - /// - [CanBeNull] - public string FileExtension { get; } - - /// - /// Content of the file. - /// - [NotNull] - public byte[] Content { get; } - - /// - /// The assembly that contains the file. - /// - [NotNull] - public Assembly Assembly { get; set; } - - /// - /// Last modification time of the file. - /// - public DateTime LastModifiedUtc { get; } - - internal EmbeddedFileInfo([NotNull] string fileName, [NotNull] byte[] content, [NotNull] Assembly assembly) - { - Check.NotNull(fileName, nameof(fileName)); - Check.NotNull(content, nameof(content)); - Check.NotNull(assembly, nameof(assembly)); - - FileName = fileName; - Content = content; - Assembly = assembly; - - FileExtension = CalculateFileExtension(FileName); - LastModifiedUtc = Assembly.Location != null - ? new FileInfo(Assembly.Location).LastWriteTimeUtc - : DateTime.UtcNow; - } - - private static string CalculateFileExtension(string fileName) - { - if (!fileName.Contains(".")) - { - return null; - } - - return fileName.Substring(fileName.LastIndexOf(".", StringComparison.Ordinal) + 1); - } - } -} \ No newline at end of file diff --git a/src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileManager.cs b/src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileManager.cs deleted file mode 100644 index 33589ed5b6..0000000000 --- a/src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileManager.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.Extensions.Options; -using Volo.Abp.DependencyInjection; - -namespace Volo.Abp.EmbeddedFiles -{ - public class EmbeddedFileManager : IEmbeddedFileManager, ISingletonDependency - { - private readonly EmbeddedFileOptions _options; - private readonly Lazy> _resources; - - /// - /// Constructor. - /// - public EmbeddedFileManager(IOptions options) - { - _options = options.Value; - _resources = new Lazy>( - CreateResourcesDictionary, - true - ); - } - - /// - public EmbeddedFileInfo FindFile(string fullPath) - { - return _resources.Value.GetOrDefault(EmbeddedFilePathHelper.NormalizePath(fullPath)); - } - - private Dictionary CreateResourcesDictionary() - { - var resources = new Dictionary(StringComparer.OrdinalIgnoreCase); - - foreach (var source in _options.Sources) - { - source.AddResources(resources); - } - - return resources; - } - } -} \ No newline at end of file diff --git a/src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileOptions.cs b/src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileOptions.cs deleted file mode 100644 index 44bc20af4b..0000000000 --- a/src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileOptions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Collections.Generic; - -namespace Volo.Abp.EmbeddedFiles -{ - public class EmbeddedFileOptions - { - public List Sources { get; } - - public EmbeddedFileOptions() - { - Sources = new List(); - } - } -} \ No newline at end of file diff --git a/src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileSet.cs b/src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileSet.cs deleted file mode 100644 index 14981250b5..0000000000 --- a/src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileSet.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; - -namespace Volo.Abp.EmbeddedFiles -{ - public class EmbeddedFileSet - { - public string RootPath { get; } - - public Assembly Assembly { get; } - - public string ResourceNamespace { get; } - - public EmbeddedFileSet(string rootPath, Assembly assembly, string resourceNamespace) - { - RootPath = rootPath.EnsureEndsWith('/'); - Assembly = assembly; - ResourceNamespace = resourceNamespace; - } - - internal void AddResources(Dictionary resources) - { - foreach (var resourceName in Assembly.GetManifestResourceNames()) - { - if (!resourceName.StartsWith(ResourceNamespace)) - { - continue; - } - - using (var stream = Assembly.GetManifestResourceStream(resourceName)) - { - var filePath = RootPath + ConvertToRelativePath(resourceName); - - resources[filePath] = new EmbeddedFileInfo( - CalculateFileName(filePath), - stream.GetAllBytes(), - Assembly - ); - } - } - } - - private string ConvertToRelativePath(string resourceName) - { - resourceName = resourceName.Substring(ResourceNamespace.Length + 1); - - var pathParts = resourceName.Split('.'); - if (pathParts.Length <= 2) - { - return resourceName; - } - - var folder = pathParts.Take(pathParts.Length - 2).Select(NormalizeFolderName).JoinAsString("/"); - var fileName = pathParts[pathParts.Length - 2] + "." + pathParts[pathParts.Length - 1]; - - return folder + "/" + fileName; - } - - private static string NormalizeFolderName(string pathPart) - { - //TODO: Implement all rules of .NET - return pathPart.Replace('-', '_'); - } - - private static string CalculateFileName(string filePath) - { - if (!filePath.Contains("/")) - { - return filePath; - } - - return filePath.Substring(filePath.LastIndexOf("/", StringComparison.Ordinal) + 1); - } - } -} \ No newline at end of file diff --git a/src/Volo.Abp/Volo/Abp/EmbeddedFiles/IEmbeddedFileManager.cs b/src/Volo.Abp/Volo/Abp/EmbeddedFiles/IEmbeddedFileManager.cs deleted file mode 100644 index de7eb4a41a..0000000000 --- a/src/Volo.Abp/Volo/Abp/EmbeddedFiles/IEmbeddedFileManager.cs +++ /dev/null @@ -1,21 +0,0 @@ -using JetBrains.Annotations; - -namespace Volo.Abp.EmbeddedFiles -{ - //TODO: Move these classes to Volo.Abp.EmbeddedResources/EmbeddedFiles project? - - /// - /// Provides infrastructure to use any type of files embedded into assemblies. - /// - public interface IEmbeddedFileManager - { - /// - /// Used to get an embedded file. - /// Can return null if file not found! - /// - /// Full path of the file - /// The resource - [CanBeNull] - EmbeddedFileInfo FindFile([NotNull] string fullResourcePath); - } -} \ No newline at end of file diff --git a/test/Volo.Abp.Tests/Volo.Abp.Tests.csproj b/test/Volo.Abp.Tests/Volo.Abp.Tests.csproj index cd561f31e3..851d4bdcbb 100644 --- a/test/Volo.Abp.Tests/Volo.Abp.Tests.csproj +++ b/test/Volo.Abp.Tests/Volo.Abp.Tests.csproj @@ -11,10 +11,6 @@ - - - - diff --git a/test/Volo.Abp.Tests/Volo/Abp/EmbeddedFiles/MyResources/js/MyScriptFile1.js b/test/Volo.Abp.Tests/Volo/Abp/EmbeddedFiles/MyResources/js/MyScriptFile1.js deleted file mode 100644 index 95bd3141be..0000000000 --- a/test/Volo.Abp.Tests/Volo/Abp/EmbeddedFiles/MyResources/js/MyScriptFile1.js +++ /dev/null @@ -1,2 +0,0 @@ -/* This file is just a sample to use in tests */ -alert('hello world!'); \ No newline at end of file diff --git a/test/Volo.Abp.VirtualFileSystem.Tests/Volo.Abp.VirtualFileSystem.Tests.csproj b/test/Volo.Abp.VirtualFileSystem.Tests/Volo.Abp.VirtualFileSystem.Tests.csproj new file mode 100644 index 0000000000..0404e6b6cf --- /dev/null +++ b/test/Volo.Abp.VirtualFileSystem.Tests/Volo.Abp.VirtualFileSystem.Tests.csproj @@ -0,0 +1,27 @@ + + + + netcoreapp2.0 + Volo.Abp.VirtualFileSystem.Tests + Volo.Abp.VirtualFileSystem.Tests + true + false + false + false + + + + + + + + + + + + + + + + + diff --git a/test/Volo.Abp.Tests/Volo/Abp/EmbeddedFiles/EmbeddedFileManager_Tests.cs b/test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/EmbeddedFileManager_Tests.cs similarity index 52% rename from test/Volo.Abp.Tests/Volo/Abp/EmbeddedFiles/EmbeddedFileManager_Tests.cs rename to test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/EmbeddedFileManager_Tests.cs index 1315baa489..bd630b6e10 100644 --- a/test/Volo.Abp.Tests/Volo/Abp/EmbeddedFiles/EmbeddedFileManager_Tests.cs +++ b/test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/EmbeddedFileManager_Tests.cs @@ -1,42 +1,52 @@ -using System.Reflection; +using System.IO; +using System.Reflection; +using System.Text; using Microsoft.Extensions.DependencyInjection; using Shouldly; using Volo.Abp.Modularity; using Volo.Abp.TestBase; +using Volo.Abp.VirtualFileSystem.Embedded; using Xunit; -namespace Volo.Abp.EmbeddedFiles +namespace Volo.Abp.VirtualFileSystem { public class EmbeddedFileManager_Tests : AbpIntegratedTest { - private readonly IEmbeddedFileManager _embeddedFileManager; + private readonly IVirtualFileProvider _embeddedFileManager; public EmbeddedFileManager_Tests() { - _embeddedFileManager = ServiceProvider.GetRequiredService(); + _embeddedFileManager = ServiceProvider.GetRequiredService(); } [Fact] public void Should_Define_And_Get_Embedded_Resources() { - var resource = _embeddedFileManager.FindFile("/MyApp/MyResources/js/MyScriptFile1.js"); + //Act + var resource = _embeddedFileManager.GetFileInfo("/MyApp/MyResources/js/jquery-3.1.1.min.js"); + //Assert resource.ShouldNotBeNull(); - Assert.Equal(resource.Assembly, GetType().GetTypeInfo().Assembly); - Assert.True(resource.Content.Length > 0); + resource.Exists.ShouldBeTrue(); + + using (var stream = resource.CreateReadStream()) + { + Encoding.UTF8.GetString(stream.GetAllBytes()).ShouldBe("//jquery-3.1.1.min.js-contents"); + } } + [DependsOn(typeof(AbpVirtualFileSystemModule))] public class TestModule : AbpModule { public override void ConfigureServices(IServiceCollection services) { - services.Configure(options => + services.Configure(options => { - options.Sources.Add( + options.FileSets.Add( new EmbeddedFileSet( "/MyApp/MyResources/", GetType().GetTypeInfo().Assembly, - "Volo.Abp.EmbeddedFiles.MyResources" + "Volo.Abp.VirtualFileSystem.MyResources" ) ); }); diff --git a/test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/MyResources/js/jquery-3.1.1.min.js b/test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/MyResources/js/jquery-3.1.1.min.js new file mode 100644 index 0000000000..4a3227cd54 --- /dev/null +++ b/test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/MyResources/js/jquery-3.1.1.min.js @@ -0,0 +1 @@ +//jquery-3.1.1.min.js-contents \ No newline at end of file