Browse Source

Revised embedded file system to better work with aspnet core razor pages.

pull/179/head
Halil İbrahim Kalkan 9 years ago
parent
commit
7f95e2810e
  1. 20
      Volo.Abp.sln
  2. 10
      src/AbpDesk/AbpDesk.MongoBlog/AbpDesk/Blogging/AbpDeskMongoBlogModule.cs
  3. 11
      src/AbpDesk/AbpDesk.Web.Mvc/AbpDeskWebMvcModule.cs
  4. 14
      src/AbpDesk/AbpDesk.Web.Mvc/Controllers/HomeController.cs
  5. 3
      src/AbpDesk/AbpDesk.Web.Mvc/Pages/Index.cshtml
  6. 12
      src/AbpDesk/AbpDesk.Web.Mvc/Pages/Index.cshtml.cs
  7. 4
      src/AbpDesk/AbpDesk.Web.Mvc/Pages/_ViewImports.cshtml
  8. 4
      src/AbpDesk/AbpDesk.Web.Mvc/Pages/_ViewStart.cshtml
  9. 7
      src/AbpDesk/AbpDesk.Web.Mvc/Temp/MyClassToTestAutofacCustomRegistration.cs
  10. 1
      src/AbpDesk/AbpDesk.Web.Mvc/Views/Home/Index.cshtml
  11. BIN
      src/AbpDesk/Web_PlugIns/AbpDesk.MongoBlog.dll
  12. 9
      src/Volo.Abp.Account.Web/AbpAccountWebModule.cs
  13. 7
      src/Volo.Abp.AspNetCore.EmbeddedFiles/Microsoft/AspNetCore/Builder/VirtualFileSystemApplicationBuilderExtensions.cs
  14. 11
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/AbpAspNetCoreMvcUiBootstrapModule.cs
  15. 9
      src/Volo.Abp.AspNetCore.Mvc.UI/AbpAspNetCoreMvcUiModule.cs
  16. 3
      src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj
  17. 0
      src/Volo.Abp.AspNetCore.Mvc.UI/wwwroot/libs/abp/abp-jquery.js
  18. 4
      src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs
  19. 15
      src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/VirtualFileSystem/AspNetCoreVirtualViewFileProvider.cs
  20. 2
      src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj
  21. 2
      src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs
  22. 34
      src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/EmbeddedFiles/EmbeddedResourceItemFileInfo.cs
  23. 20
      src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/EmbeddedFiles/EmbeddedResourceViewFileProvider.cs
  24. 10
      src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/AspNetCoreVirtualFileOptions.cs
  25. 51
      src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/AspNetCoreVirtualFileProvider.cs
  26. 24
      src/Volo.Abp.Identity.Web/AbpIdentityWebModule.cs
  27. 8
      src/Volo.Abp.Identity.Web/Areas/Identity/Controllers/UsersController.cs
  28. 48
      src/Volo.Abp.Identity.Web/Pages/Identity/Users/Index.cshtml
  29. 12
      src/Volo.Abp.Identity.Web/Pages/Identity/Users/Index.cshtml.cs
  30. 4
      src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.csproj
  31. 24
      src/Volo.Abp.VirtualFileSystem/Volo.Abp.VirtualFileSystem.csproj
  32. 13
      src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/AbpVirtualFileSystemModule.cs
  33. 129
      src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/EmbeddedFileSet.cs
  34. 90
      src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/EmbeddedResourceFileInfo.cs
  35. 4
      src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/EmbeddedFilePathHelper.cs
  36. 31
      src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/EnumerableDirectoryContents.cs
  37. 8
      src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/IEmbeddedFileManager.cs
  38. 10
      src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/IVirtualFileSet.cs
  39. 89
      src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileProvider.cs
  40. 14
      src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileSystemOptions.cs
  41. 68
      src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileInfo.cs
  42. 43
      src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileManager.cs
  43. 14
      src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileOptions.cs
  44. 78
      src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileSet.cs
  45. 21
      src/Volo.Abp/Volo/Abp/EmbeddedFiles/IEmbeddedFileManager.cs
  46. 4
      test/Volo.Abp.Tests/Volo.Abp.Tests.csproj
  47. 2
      test/Volo.Abp.Tests/Volo/Abp/EmbeddedFiles/MyResources/js/MyScriptFile1.js
  48. 27
      test/Volo.Abp.VirtualFileSystem.Tests/Volo.Abp.VirtualFileSystem.Tests.csproj
  49. 30
      test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/EmbeddedFileManager_Tests.cs
  50. 1
      test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/MyResources/js/jquery-3.1.1.min.js

20
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}

10
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<EmbeddedFileOptions>(options =>
services.Configure<VirtualFileSystemOptions>(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,

11
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<AbpDeskWebMvcModule>();
services.GetContainerBuilder().RegisterType<MyClassToTestAutofacCustomRegistration>();
services.Configure<BundlingOptions>(options =>
{
options.ScriptBundles.Add("GlobalScripts", new[]
@ -87,7 +80,7 @@ namespace AbpDesk.Web.Mvc
}
app.UseStaticFiles();
app.UseEmbeddedFiles();
app.UseVirtualFiles();
app.UseAuthentication();

14
src/AbpDesk/AbpDesk.Web.Mvc/Controllers/HomeController.cs

@ -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();
}
}
}

3
src/AbpDesk/AbpDesk.Web.Mvc/Pages/Index.cshtml

@ -0,0 +1,3 @@
@page
@model AbpDesk.Web.Mvc.Pages.IndexModel
<h2>Home page!</h2>

12
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()
{
}
}
}

4
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

4
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";
}

7
src/AbpDesk/AbpDesk.Web.Mvc/Temp/MyClassToTestAutofacCustomRegistration.cs

@ -1,7 +0,0 @@
namespace AbpDesk.Web.Mvc.Temp
{
/* Will be removed later */
public class MyClassToTestAutofacCustomRegistration
{
}
}

1
src/AbpDesk/AbpDesk.Web.Mvc/Views/Home/Index.cshtml

@ -1 +0,0 @@
<h2>Home</h2>

BIN
src/AbpDesk/Web_PlugIns/AbpDesk.MongoBlog.dll

Binary file not shown.

9
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<AbpAccountWebModule>();
services.Configure<EmbeddedFileOptions>(options =>
services.Configure<VirtualFileSystemOptions>(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,

7
src/Volo.Abp.AspNetCore.EmbeddedFiles/Microsoft/AspNetCore/Builder/EmbeddedFilesApplicationBuilderExtensions.cs → 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
)
}

11
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<AbpAspNetCoreMvcUiBootstrapModule>();
services.Configure<EmbeddedFileOptions>(options =>
services.Configure<VirtualFileSystemOptions>(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?
});
});
}

9
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<AbpAspNetCoreMvcUiModule>();
services.Configure<EmbeddedFileOptions>(options =>
services.Configure<VirtualFileSystemOptions>(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,

3
src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj

@ -19,12 +19,11 @@
</ItemGroup>
<ItemGroup>
<None Remove="wwwroot\libs\abp\abp.jquery.js" />
<None Remove="wwwroot\libs\abp\abp.js" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="wwwroot\libs\abp\abp.jquery.js" />
<EmbeddedResource Include="wwwroot\libs\abp\abp-jquery.js" />
<EmbeddedResource Include="wwwroot\libs\abp\abp.js" />
</ItemGroup>

0
src/Volo.Abp.AspNetCore.Mvc.UI/wwwroot/libs/abp/abp.jquery.js → src/Volo.Abp.AspNetCore.Mvc.UI/wwwroot/libs/abp/abp-jquery.js

4
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<RazorViewEngineOptions>(options =>
{
options.FileProviders.Add(
new EmbeddedResourceViewFileProvider(
new AspNetCoreVirtualViewFileProvider(
services.GetSingletonInstance<IObjectAccessor<IServiceProvider>>()
)
);

15
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<IServiceProvider> serviceProviderAccessor)
: base(serviceProviderAccessor)
{
}
}
}

2
src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj

@ -14,7 +14,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp\Volo.Abp.csproj" />
<ProjectReference Include="..\Volo.Abp.VirtualFileSystem\Volo.Abp.VirtualFileSystem.csproj" />
</ItemGroup>
<ItemGroup>

2
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)

34
src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/EmbeddedFiles/EmbeddedResourceItemFileInfo.cs

@ -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);
}
}
}

20
src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/EmbeddedFiles/EmbeddedResourceViewFileProvider.cs

@ -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<IServiceProvider> serviceProviderAccessor)
: base(serviceProviderAccessor)
{
}
protected override bool IsIgnoredFile(EmbeddedFileInfo resource)
{
return resource.FileExtension != "cshtml";
}
}
}

10
src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/EmbeddedFiles/AspNetCoreEmbeddedFileOptions.cs → 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<string> IgnoredFileExtensions { get; }
public AspNetCoreEmbeddedFileOptions()
public AspNetCoreVirtualFileOptions()
{
IgnoredFileExtensions = new HashSet<string>
{
"cshtml",
"config"
".cshtml",
".config"
};
}
}

51
src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/EmbeddedFiles/EmbeddedResourceFileProvider.cs → 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<IEmbeddedFileManager> _embeddedResourceManager;
private readonly Lazy<AspNetCoreEmbeddedFileOptions> _options;
private readonly Lazy<IVirtualFileProvider> _embeddedResourceManager;
private readonly Lazy<AspNetCoreVirtualFileOptions> _options;
private readonly IObjectAccessor<IServiceProvider> _serviceProviderAccessor;
public EmbeddedResourceFileProvider(IServiceProvider serviceProvider)
public AspNetCoreVirtualFileProvider(IServiceProvider serviceProvider)
: this(new ObjectAccessor<IServiceProvider>(serviceProvider))
{
}
public EmbeddedResourceFileProvider(IObjectAccessor<IServiceProvider> serviceProviderAccessor)
public AspNetCoreVirtualFileProvider(IObjectAccessor<IServiceProvider> serviceProviderAccessor)
{
_serviceProviderAccessor = serviceProviderAccessor;
_embeddedResourceManager = new Lazy<IEmbeddedFileManager>(
() => serviceProviderAccessor.Value.GetRequiredService<IEmbeddedFileManager>(),
_embeddedResourceManager = new Lazy<IVirtualFileProvider>(
() => serviceProviderAccessor.Value.GetRequiredService<IVirtualFileProvider>(),
true
);
_options = new Lazy<AspNetCoreEmbeddedFileOptions>(
() => serviceProviderAccessor.Value.GetRequiredService<IOptions<AspNetCoreEmbeddedFileOptions>>().Value,
_options = new Lazy<AspNetCoreVirtualFileOptions>(
() => serviceProviderAccessor.Value.GetRequiredService<IOptions<AspNetCoreVirtualFileOptions>>().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()

24
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<EmbeddedFileOptions>(options =>
services.Configure<VirtualFileSystemOptions>(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"
)
);

8
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<ActionResult> Index()
{
return View();
}
//public async Task<ActionResult> Index()
//{
// return View();
//}
public async Task<PartialViewResult> Create()
{

48
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<IdentityResource> L
@section styles {
<!-- TODO: Use minified on production, normal in development -->
<link rel="stylesheet" type="text/css" href="~/modules/identity/libs/datatables/datatables.css" />
<link rel="stylesheet" type="text/css" href="~/modules/identity/views/users/index.css" />
}
@section scripts {
<!-- TODO: Use minified on production, normal in development -->
<script type="text/javascript" src="~/modules/identity/libs/datatables/datatables.min.js"></script>
<script type="text/javascript" src="~/modules/identity/views/users/index.js"></script>
}
<div class="row">
<div class="col-md-6">
<h2>@L["Users"]</h2>
</div>
<div class="col-md-6 text-right">
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary create-user" data-toggle="modal">
@L["CreateUser"]
</button>
</div>
</div>
<table id="IdentityUsersTable" class="table table-striped table-bordered table-hover nowrap">
<thead>
<tr>
<th>@L["Actions"]</th>
<th>@L["UserName"]</th>
<th>@L["EmailAddress"]</th>
<th>@L["PhoneNumber"]</th>
</tr>
</thead>
</table>
<!-- Modal -->
<div class="modal fade" id="createUpdateUserModal" tabindex="-1" role="dialog" aria-labelledby="userModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
</div>
</div>
</div>

12
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()
{
}
}
}

4
src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.csproj

@ -17,6 +17,10 @@
<EmbeddedResource Include="wwwroot\**\*.*" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Pages\Identity\Users\Index.cshtml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.UI.Bootstrap\Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.csproj" />
<ProjectReference Include="..\Volo.Abp.Identity.Application.Contracts\Volo.Abp.Identity.Application.Contracts.csproj" />

24
src/Volo.Abp.VirtualFileSystem/Volo.Abp.VirtualFileSystem.csproj

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>Volo.Abp.VirtualFileSystem</AssemblyName>
<PackageId>Volo.Abp.VirtualFileSystem</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.FileProviders.Abstractions" Version="2.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp\Volo.Abp.csproj" />
</ItemGroup>
</Project>

13
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<AbpVirtualFileSystemModule>();
}
}
}

129
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<string, IFileInfo> 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<string, IFileInfo> 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);
}
}
}

90
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
{
/// <summary>
/// Represents a file embedded in an assembly.
/// </summary>
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; }
/// <summary>
/// The time, in UTC.
/// </summary>
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;
}
/// <inheritdoc />
public Stream CreateReadStream()
{
var stream = _assembly.GetManifestResourceStream(_resourcePath);
if (!_length.HasValue)
{
_length = stream.Length;
}
return stream;
}
public override string ToString()
{
return $"[EmbeddedResourceFileInfo] {Name} ({PhysicalPath})";
}
}
}

4
src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFilePathHelper.cs → 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)
{

31
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<IFileInfo> _entries;
public EnumerableDirectoryContents([NotNull] IEnumerable<IFileInfo> entries)
{
Check.NotNull(entries, nameof(entries));
_entries = entries;
}
public bool Exists => true;
public IEnumerator<IFileInfo> GetEnumerator()
{
return _entries.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _entries.GetEnumerator();
}
}
}

8
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
{
}
}

10
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<string, IFileInfo> files);
}
}

89
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<Dictionary<string, IFileInfo>> _files;
public VirtualFileProvider(IOptions<VirtualFileSystemOptions> options)
{
_options = options.Value;
_files = new Lazy<Dictionary<string, IFileInfo>>(
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<IFileInfo>();
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<string, IFileInfo> CreateResourcesDictionary()
{
var files = new Dictionary<string, IFileInfo>(StringComparer.OrdinalIgnoreCase);
foreach (var set in _options.FileSets)
{
set.AddFiles(files);
}
return files;
}
}
}

14
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<IVirtualFileSet> FileSets { get; }
public VirtualFileSystemOptions()
{
FileSets = new List<IVirtualFileSet>();
}
}
}

68
src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileInfo.cs

@ -1,68 +0,0 @@
using System;
using System.IO;
using System.Reflection;
using JetBrains.Annotations;
namespace Volo.Abp.EmbeddedFiles
{
/// <summary>
/// Stores needed information of an embedded resource.
/// </summary>
public class EmbeddedFileInfo
{
/// <summary>
/// File name including extension.
/// </summary>
[NotNull]
public string FileName { get; }
/// <summary>
/// File extension (without dot) if available.
/// </summary>
[CanBeNull]
public string FileExtension { get; }
/// <summary>
/// Content of the file.
/// </summary>
[NotNull]
public byte[] Content { get; }
/// <summary>
/// The assembly that contains the file.
/// </summary>
[NotNull]
public Assembly Assembly { get; set; }
/// <summary>
/// Last modification time of the file.
/// </summary>
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);
}
}
}

43
src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileManager.cs

@ -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<Dictionary<string, EmbeddedFileInfo>> _resources;
/// <summary>
/// Constructor.
/// </summary>
public EmbeddedFileManager(IOptions<EmbeddedFileOptions> options)
{
_options = options.Value;
_resources = new Lazy<Dictionary<string, EmbeddedFileInfo>>(
CreateResourcesDictionary,
true
);
}
/// <inheritdoc/>
public EmbeddedFileInfo FindFile(string fullPath)
{
return _resources.Value.GetOrDefault(EmbeddedFilePathHelper.NormalizePath(fullPath));
}
private Dictionary<string, EmbeddedFileInfo> CreateResourcesDictionary()
{
var resources = new Dictionary<string, EmbeddedFileInfo>(StringComparer.OrdinalIgnoreCase);
foreach (var source in _options.Sources)
{
source.AddResources(resources);
}
return resources;
}
}
}

14
src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileOptions.cs

@ -1,14 +0,0 @@
using System.Collections.Generic;
namespace Volo.Abp.EmbeddedFiles
{
public class EmbeddedFileOptions
{
public List<EmbeddedFileSet> Sources { get; }
public EmbeddedFileOptions()
{
Sources = new List<EmbeddedFileSet>();
}
}
}

78
src/Volo.Abp/Volo/Abp/EmbeddedFiles/EmbeddedFileSet.cs

@ -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<string, EmbeddedFileInfo> 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);
}
}
}

21
src/Volo.Abp/Volo/Abp/EmbeddedFiles/IEmbeddedFileManager.cs

@ -1,21 +0,0 @@
using JetBrains.Annotations;
namespace Volo.Abp.EmbeddedFiles
{
//TODO: Move these classes to Volo.Abp.EmbeddedResources/EmbeddedFiles project?
/// <summary>
/// Provides infrastructure to use any type of files embedded into assemblies.
/// </summary>
public interface IEmbeddedFileManager
{
/// <summary>
/// Used to get an embedded file.
/// Can return null if file not found!
/// </summary>
/// <param name="fullResourcePath">Full path of the file</param>
/// <returns>The resource</returns>
[CanBeNull]
EmbeddedFileInfo FindFile([NotNull] string fullResourcePath);
}
}

4
test/Volo.Abp.Tests/Volo.Abp.Tests.csproj

@ -11,10 +11,6 @@
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Volo\Abp\EmbeddedFiles\MyResources\js\*.js" Exclude="bin\**;obj\**;**\*.xproj;packages\**;@(EmbeddedResource)" />
</ItemGroup>
<ItemGroup>
<None Remove="Volo\Abp\Localization\Source\en.json" />
<None Remove="Volo\Abp\Localization\Source\tr.json" />

2
test/Volo.Abp.Tests/Volo/Abp/EmbeddedFiles/MyResources/js/MyScriptFile1.js

@ -1,2 +0,0 @@
/* This file is just a sample to use in tests */
alert('hello world!');

27
test/Volo.Abp.VirtualFileSystem.Tests/Volo.Abp.VirtualFileSystem.Tests.csproj

@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<AssemblyName>Volo.Abp.VirtualFileSystem.Tests</AssemblyName>
<PackageId>Volo.Abp.VirtualFileSystem.Tests</PackageId>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Volo\Abp\VirtualFileSystem\MyResources\js\jquery-3.1.1.min.js" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" />
<ProjectReference Include="..\..\src\Volo.Abp.VirtualFileSystem\Volo.Abp.VirtualFileSystem.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
</ItemGroup>
</Project>

30
test/Volo.Abp.Tests/Volo/Abp/EmbeddedFiles/EmbeddedFileManager_Tests.cs → 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<EmbeddedFileManager_Tests.TestModule>
{
private readonly IEmbeddedFileManager _embeddedFileManager;
private readonly IVirtualFileProvider _embeddedFileManager;
public EmbeddedFileManager_Tests()
{
_embeddedFileManager = ServiceProvider.GetRequiredService<IEmbeddedFileManager>();
_embeddedFileManager = ServiceProvider.GetRequiredService<IVirtualFileProvider>();
}
[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<EmbeddedFileOptions>(options =>
services.Configure<VirtualFileSystemOptions>(options =>
{
options.Sources.Add(
options.FileSets.Add(
new EmbeddedFileSet(
"/MyApp/MyResources/",
GetType().GetTypeInfo().Assembly,
"Volo.Abp.EmbeddedFiles.MyResources"
"Volo.Abp.VirtualFileSystem.MyResources"
)
);
});

1
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
Loading…
Cancel
Save