Browse Source

Use virtual file provider to read embedded localization jsons.

pull/183/head
Halil İbrahim Kalkan 9 years ago
parent
commit
12e38bf7e0
  1. BIN
      src/AbpDesk/Web_PlugIns/AbpDesk.MongoBlog.dll
  2. 21
      src/Volo.Abp.AspNetCore.EmbeddedFiles/Microsoft/AspNetCore/Builder/VirtualFileSystemApplicationBuilderExtensions.cs
  3. 4
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/AbpAspNetCoreMvcUiBootstrapModule.cs
  4. 2
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/Localization/Resources/AbpBootstrap/AbpBootstrapResource.cs
  5. 0
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/Localization/Resources/AbpBootstrap/en.json
  6. 0
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/Localization/Resources/AbpBootstrap/tr.json
  7. 2
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalFooterTagHelper.cs
  8. 93
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.csproj
  9. 2
      src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj
  10. 24
      src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/AspNetCoreVirtualFileProvider.cs
  11. 5
      src/Volo.Abp.Identity.Web/AbpIdentityWebModule.cs
  12. 12
      src/Volo.Abp.Identity.Web/Localization/Resource/IdentityResource.cs
  13. 12
      src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/IdentityResource.cs
  14. 0
      src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/en.json
  15. 0
      src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/tr.json
  16. 2
      src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml
  17. 2
      src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml
  18. 2
      src/Volo.Abp.Identity.Web/Pages/Identity/Users/Index.cshtml
  19. 4
      src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.csproj
  20. 1
      src/Volo.Abp.Localization/Volo.Abp.Localization.csproj
  21. 11
      src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationModule.cs
  22. 50
      src/Volo.Abp.Localization/Volo/Abp/Localization/Json/JsonEmbeddedFileLocalizationDictionaryProvider.cs
  23. 23
      src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceListExtensions.cs
  24. 2
      src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpValidation/AbpValidationResource.cs
  25. 0
      src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpValidation/en.json
  26. 0
      src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpValidation/tr.json
  27. 25
      src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/Json/JsonEmbeddedFileLocalizationDictionaryProvider.cs
  28. 48
      src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/VirtualFileLocalizationDictionaryProviderBase.cs
  29. 1
      src/Volo.Abp.VirtualFileSystem/Volo.Abp.VirtualFileSystem.csproj
  30. 5
      src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/EmbeddedFileSet.cs
  31. 125
      src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileProvider.cs
  32. 5
      src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileSetListExtensions.cs
  33. 21
      test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs
  34. 7
      test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/SourceExt/SourceExt.cs
  35. 2
      test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/LocalizationTestCountryNamesResource.cs
  36. 0
      test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/en.json
  37. 0
      test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/tr.json
  38. 2
      test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/LocalizationTestValidationResource.cs
  39. 0
      test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/en.json
  40. 6
      test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/LocalizationTestResource.cs
  41. 0
      test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/en.json
  42. 0
      test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/tr.json
  43. 0
      test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/en.json
  44. 0
      test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/it.json

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

Binary file not shown.

21
src/Volo.Abp.AspNetCore.EmbeddedFiles/Microsoft/AspNetCore/Builder/VirtualFileSystemApplicationBuilderExtensions.cs

@ -11,24 +11,25 @@ namespace Microsoft.AspNetCore.Builder
{
public static void UseVirtualFiles(this IApplicationBuilder app)
{
var options = app.ApplicationServices.GetRequiredService<IOptions<VirtualFileSystemOptions>>().Value;
//var options = app.ApplicationServices.GetRequiredService<IOptions<VirtualFileSystemOptions>>().Value;
IFileProvider fileProvider = new AspNetCoreVirtualFileProvider(
app.ApplicationServices,
"/wwwroot"
);
if (options.FileSets.PhysicalPaths.Any())
{
var fileProviders = options.FileSets.PhysicalPaths
.Select(p => new PhysicalFileProvider(p))
.Cast<IFileProvider>()
.ToList();
////TODO: This should not be needed!!!
//if (options.FileSets.PhysicalPaths.Any())
//{
// var fileProviders = options.FileSets.PhysicalPaths
// .Select(p => new PhysicalFileProvider(p))
// .Cast<IFileProvider>()
// .ToList();
fileProviders.Add(fileProvider);
// fileProviders.Add(fileProvider);
fileProvider = new CompositeFileProvider(fileProviders);
}
// fileProvider = new CompositeFileProvider(fileProviders);
//}
app.UseStaticFiles(
new StaticFileOptions

4
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/AbpAspNetCoreMvcUiBootstrapModule.cs

@ -1,7 +1,7 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Mvc.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Localization.Resource;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Localization.Resources.AbpBootstrap;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
@ -22,7 +22,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap
services.Configure<AbpLocalizationOptions>(options =>
{
options.Resources.AddJson<AbpBootstrapResource>("en");
options.Resources.AddVirtualJson<AbpBootstrapResource>("en", "/Localization/Resources/AbpBootstrap");
});
services.Configure<BundlingOptions>(options =>

2
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/Localization/Resource/AbpBootstrapResource.cs → src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/Localization/Resources/AbpBootstrap/AbpBootstrapResource.cs

@ -1,4 +1,4 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Localization.Resource
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Localization.Resources.AbpBootstrap
{
public class AbpBootstrapResource
{

0
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/Localization/Resource/en.json → src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/Localization/Resources/AbpBootstrap/en.json

0
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/Localization/Resource/tr.json → src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/Localization/Resources/AbpBootstrap/tr.json

2
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Modal/AbpModalFooterTagHelper.cs

@ -1,7 +1,7 @@
using System.Text;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.Localization;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Localization.Resource;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Localization.Resources.AbpBootstrap;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
{

93
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.csproj

@ -10,101 +10,18 @@
</PropertyGroup>
<ItemGroup>
<None Remove="Localization\Resource\en.json" />
<None Remove="Localization\Resource\tr.json" />
</ItemGroup>
<ItemGroup>
<Content Include="Localization\Resource\tr.json">
<Content Include="Localization\Resources\AbpBootstrap\tr.json">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="Localization\Resource\en.json">
<Content Include="Localization\Resources\AbpBootstrap\en.json">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Localization\Resource\*.json" />
<EmbeddedResource Include="Views\Shared\Components\AbpMenu\Default.cshtml" />
<EmbeddedResource Include="Views\Shared\_AppLayout.cshtml" />
<EmbeddedResource Include="wwwroot\libs\datatables\datatables.css" />
<EmbeddedResource Include="wwwroot\libs\datatables\datatables.js" />
<EmbeddedResource Include="wwwroot\libs\datatables\datatables.min.css" />
<EmbeddedResource Include="wwwroot\libs\datatables\datatables.min.js" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Afrikaans.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Albanian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Arabic.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Armenian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Azerbaijan.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Bangla.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Basque.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Belarusian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Bulgarian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Catalan.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Chinese (Simplified, China).json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Chinese-traditional.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Croatian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Czech.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Danish.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Dutch.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\English.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Estonian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Filipino.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Finnish.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\French.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Galician.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Georgian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\German.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Greek.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Gujarati.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Hebrew.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Hindi.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Hungarian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Icelandic.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Indonesian-Alternative.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Indonesian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Irish.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Italian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Japanese.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Kazakh.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Korean.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Kyrgyz.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Latvian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Lithuanian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Macedonian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Malay.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Mongolian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Nepali.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Norwegian-Bokmal.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Norwegian-Nynorsk.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Pashto.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Persian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Polish.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Portuguese (Brazil).json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Portuguese.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Romanian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Russian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Serbian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Sinhala.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Slovak.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Slovenian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Spanish.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Swahili.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Swedish.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Tamil.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\telugu.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Thai.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Turkish.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Ukrainian.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Urdu.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Uzbek.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Vietnamese.json" />
<EmbeddedResource Include="wwwroot\libs\datatables\localizations\Welsh.json" />
<EmbeddedResource Include="wwwroot\views\shared\_AppLayout.css" />
<EmbeddedResource Include="Views\Shared\_ViewImports.cshtml" />
<EmbeddedResource Include="wwwroot\libs\jquery\jquery-3.1.1.js" />
<EmbeddedResource Include="wwwroot\libs\jquery\jquery-3.1.1.min.js" />
<EmbeddedResource Include="wwwroot\libs\jquery\jquery-3.1.1.min.map" />
<EmbeddedResource Include="Localization\Resources\**\*.json" />
<EmbeddedResource Include="Views\**\*.cshtml" />
<EmbeddedResource Include="wwwroot\**\*.*" />
</ItemGroup>
<ItemGroup>

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

@ -19,8 +19,6 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.FileProviders.Composite" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Physical" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Routing.Abstractions" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.0.0" />

24
src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/AspNetCoreVirtualFileProvider.cs

@ -1,8 +1,6 @@
using System;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
using Volo.Abp.DependencyInjection;
using Volo.Abp.VirtualFileSystem;
@ -24,28 +22,8 @@ namespace Volo.Abp.AspNetCore.VirtualFileSystem
public AspNetCoreVirtualFileProvider(IObjectAccessor<IServiceProvider> serviceProviderAccessor)
{
_serviceProviderAccessor = serviceProviderAccessor;
_fileProvider = new Lazy<IFileProvider>(
() =>
{
var options = serviceProviderAccessor.Value.GetRequiredService<IOptions<VirtualFileSystemOptions>>().Value;
IFileProvider fileProvider = serviceProviderAccessor.Value.GetRequiredService<IVirtualFileProvider>();
if (options.FileSets.PhysicalPaths.Any())
{
var fileProviders = options.FileSets.PhysicalPaths
.Select(p => new PhysicalFileProvider(p))
.Cast<IFileProvider>()
.ToList();
fileProviders.Add(fileProvider);
fileProvider = new CompositeFileProvider(fileProviders);
}
return fileProvider;
},
() => serviceProviderAccessor.Value.GetRequiredService<IVirtualFileProvider>(),
true
);
}

5
src/Volo.Abp.Identity.Web/AbpIdentityWebModule.cs

@ -2,7 +2,7 @@
using Volo.Abp.AspNetCore.Mvc.Localization;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap;
using Volo.Abp.AutoMapper;
using Volo.Abp.Identity.Web.Localization.Resource;
using Volo.Abp.Identity.Web.Localization.Resources.AbpIdentity;
using Volo.Abp.Identity.Web.Navigation;
using Volo.Abp.Identity.Web.ObjectMappings;
using Volo.Abp.Localization;
@ -41,7 +41,8 @@ namespace Volo.Abp.Identity.Web
services.Configure<AbpLocalizationOptions>(options =>
{
options.Resources.AddJson<IdentityResource>("en");
//options.Resources.AddVirtual<IdentityResource>("en");
options.Resources.AddVirtualJson<IdentityResource>("en", "/Localization/Resources/AbpIdentity");
});
services.Configure<AbpAutoMapperOptions>(options =>

12
src/Volo.Abp.Identity.Web/Localization/Resource/IdentityResource.cs

@ -1,12 +0,0 @@
using Volo.Abp.Localization;
using Volo.Abp.Localization.Resources.Validation;
namespace Volo.Abp.Identity.Web.Localization.Resource
{
[ShortLocalizationResourceName("AbpIdentity")]
[InheritResource(typeof(AbpValidationResource))]
public class IdentityResource
{
}
}

12
src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/IdentityResource.cs

@ -0,0 +1,12 @@
using Volo.Abp.Localization;
using Volo.Abp.Localization.Resources.AbpValidation;
namespace Volo.Abp.Identity.Web.Localization.Resources.AbpIdentity
{
[ShortLocalizationResourceName("AbpIdentity")]
[InheritResource(typeof(AbpValidationResource))]
public class IdentityResource //TODO: Rename to AbpIdentityResource
{
}
}

0
src/Volo.Abp.Identity.Web/Localization/Resource/en.json → src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/en.json

0
src/Volo.Abp.Identity.Web/Localization/Resource/tr.json → src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/tr.json

2
src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml

@ -1,6 +1,6 @@
@page
@using Microsoft.Extensions.Localization
@using Volo.Abp.Identity.Web.Localization.Resource
@using Volo.Abp.Identity.Web.Localization.Resources.AbpIdentity
@model Volo.Abp.Identity.Web.Pages.Identity.Users.CreateModalModel
@inject IStringLocalizer<IdentityResource> L
@{

2
src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml

@ -1,6 +1,6 @@
@page
@using Microsoft.Extensions.Localization
@using Volo.Abp.Identity.Web.Localization.Resource
@using Volo.Abp.Identity.Web.Localization.Resources.AbpIdentity
@model Volo.Abp.Identity.Web.Pages.Identity.Users.EditModalModel
@inject IStringLocalizer<IdentityResource> L
@{

2
src/Volo.Abp.Identity.Web/Pages/Identity/Users/Index.cshtml

@ -1,7 +1,7 @@
@page
@model Volo.Abp.Identity.Web.Pages.Identity.Users.IndexModel
@using Microsoft.AspNetCore.Mvc.Localization
@using Volo.Abp.Identity.Web.Localization.Resource
@using Volo.Abp.Identity.Web.Localization.Resources.AbpIdentity
@inject IHtmlLocalizer<IdentityResource> L
@section styles {
<link rel="stylesheet" type="text/css" href="~/modules/identity/views/users/index.css" />

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

@ -13,7 +13,7 @@
<ItemGroup>
<EmbeddedResource Include="wwwroot\**\*.*" />
<EmbeddedResource Include="Pages\**\*.cshtml" />
<EmbeddedResource Include="Localization\Resource\*.json" />
<EmbeddedResource Include="Localization\Resources\**\*.json" />
</ItemGroup>
<ItemGroup>
@ -27,7 +27,7 @@
<None Remove="wwwroot\modules\identity\helpers\datatables_helper.js" />
<None Remove="wwwroot\modules\identity\helpers\jquery.js" />
</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" />

1
src/Volo.Abp.Localization/Volo.Abp.Localization.csproj

@ -19,6 +19,7 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" />
<ProjectReference Include="..\Volo.Abp.VirtualFileSystem\Volo.Abp.VirtualFileSystem.csproj" />
</ItemGroup>
</Project>

11
src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationModule.cs

@ -1,18 +1,25 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Localization.Resources.Validation;
using Volo.Abp.Localization.Resources.AbpValidation;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.Localization
{
[DependsOn(typeof(AbpVirtualFileSystemModule))]
public class AbpLocalizationModule : AbpModule
{
public override void ConfigureServices(IServiceCollection services)
{
AbpStringLocalizerFactory.Replace(services);
services.Configure<VirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpLocalizationModule>("Volo.Abp", "Volo/Abp");
});
services.Configure<AbpLocalizationOptions>(options =>
{
options.Resources.AddJson<AbpValidationResource>("en");
options.Resources.AddVirtualJson<AbpValidationResource>("en", "/Localization/Resources/AbpValidation");
});
services.AddAssemblyOf<AbpLocalizationModule>();

50
src/Volo.Abp.Localization/Volo/Abp/Localization/Json/JsonEmbeddedFileLocalizationDictionaryProvider.cs

@ -1,50 +0,0 @@
using System.Reflection;
using Volo.Abp.Internal;
namespace Volo.Abp.Localization.Json
{
/// <summary>
/// Provides localization dictionaries from JSON files embedded into an <see cref="Assembly"/>.
/// </summary>
public class JsonEmbeddedFileLocalizationDictionaryProvider : LocalizationDictionaryProviderBase
{
private readonly Assembly _assembly;
private readonly string _rootNamespace;
public JsonEmbeddedFileLocalizationDictionaryProvider(Assembly assembly, string rootNamespace)
{
_assembly = assembly;
_rootNamespace = rootNamespace;
}
public override void Initialize(LocalizationResourceInitializationContext context) //TODO: Extract initialization to a factory..?
{
var rootNameSpaceWithDot = _rootNamespace + ".";
var resourceNames = _assembly.GetManifestResourceNames();
foreach (var resourceName in resourceNames)
{
if (resourceName.StartsWith(rootNameSpaceWithDot))
{
using (var stream = _assembly.GetManifestResourceStream(resourceName))
{
var jsonString = Utf8Helper.ReadStringFromStream(stream);
var dictionary = CreateJsonLocalizationDictionary(jsonString);
if (Dictionaries.ContainsKey(dictionary.CultureName))
{
throw new AbpException($"{resourceName} dictionary has a culture name '{dictionary.CultureName}' which is already defined!");
}
Dictionaries[dictionary.CultureName] = dictionary;
}
}
}
}
protected virtual ILocalizationDictionary CreateJsonLocalizationDictionary(string jsonString)
{
return JsonLocalizationDictionaryBuilder.BuildFromJsonString(jsonString);
}
}
}

23
src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceListExtensions.cs

@ -1,15 +1,23 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using Volo.Abp.Localization.Json;
using Volo.Abp.Localization.VirtualFiles.Json;
namespace Volo.Abp.Localization
{
public static class LocalizationResourceListExtensions
{
public static LocalizationResource AddJson<TResource>([NotNull] this LocalizationResourceDictionary resourceDictionary, [NotNull] string defaultCultureName)
public static LocalizationResource AddVirtualJson<TResource>(
[NotNull] this LocalizationResourceDictionary resourceDictionary,
[NotNull] string defaultCultureName,
[NotNull] string virtualPath)
{
Check.NotNull(resourceDictionary, nameof(resourceDictionary));
Check.NotNull(defaultCultureName, nameof(defaultCultureName));
Check.NotNull(virtualPath, nameof(virtualPath));
virtualPath = virtualPath.EnsureStartsWith('/');
var resourceType = typeof(TResource);
@ -22,18 +30,18 @@ namespace Volo.Abp.Localization
resourceType,
defaultCultureName,
new JsonEmbeddedFileLocalizationDictionaryProvider(
resourceType.Assembly,
resourceType.Namespace
virtualPath
)
);
}
public static void ExtendWithJson<TResource, TResourceExt>([NotNull] this LocalizationResourceDictionary resourceDictionary)
public static void ExtendWithVirtualJson<TResource>(
[NotNull] this LocalizationResourceDictionary resourceDictionary,
[NotNull] string virtualPath)
{
Check.NotNull(resourceDictionary, nameof(resourceDictionary));
var resourceType = typeof(TResource);
var resourceExtType = typeof(TResourceExt);
var resource = resourceDictionary.GetOrDefault(resourceType);
if (resource == null)
@ -42,8 +50,7 @@ namespace Volo.Abp.Localization
}
resource.Extensions.Add(new JsonEmbeddedFileLocalizationDictionaryProvider(
resourceExtType.Assembly,
resourceExtType.Namespace
virtualPath
));
}
}

2
src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/Validation/IdentityResource.cs → src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpValidation/AbpValidationResource.cs

@ -1,4 +1,4 @@
namespace Volo.Abp.Localization.Resources.Validation
namespace Volo.Abp.Localization.Resources.AbpValidation
{
[ShortLocalizationResourceName("AbpValidation")]
public class AbpValidationResource

0
src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/Validation/en.json → src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpValidation/en.json

0
src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/Validation/tr.json → src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpValidation/tr.json

25
src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/Json/JsonEmbeddedFileLocalizationDictionaryProvider.cs

@ -0,0 +1,25 @@
using Microsoft.Extensions.FileProviders;
using System;
using Volo.Abp.Localization.Json;
namespace Volo.Abp.Localization.VirtualFiles.Json
{
public class JsonEmbeddedFileLocalizationDictionaryProvider : VirtualFileLocalizationDictionaryProviderBase
{
public JsonEmbeddedFileLocalizationDictionaryProvider(string virtualPath)
: base(virtualPath)
{
}
protected override bool CanParseFile(IFileInfo file)
{
return file.Name.EndsWith(".json", StringComparison.OrdinalIgnoreCase);
}
protected override ILocalizationDictionary CreateDictionary(string jsonString)
{
return JsonLocalizationDictionaryBuilder.BuildFromJsonString(jsonString); //TODO: Use composition over inheritance!
}
}
}

48
src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/VirtualFileLocalizationDictionaryProviderBase.cs

@ -0,0 +1,48 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Volo.Abp.Internal;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.Localization.VirtualFiles
{
public abstract class VirtualFileLocalizationDictionaryProviderBase : LocalizationDictionaryProviderBase
{
private readonly string _virtualPath;
protected VirtualFileLocalizationDictionaryProviderBase(string virtualPath)
{
_virtualPath = virtualPath;
}
public override void Initialize(LocalizationResourceInitializationContext context) //TODO: Extract initialization to a factory..?
{
var virtualFileProvider = context.ServiceProvider.GetRequiredService<IVirtualFileProvider>();
var directoryContents = virtualFileProvider.GetDirectoryContents(_virtualPath);
foreach (var file in directoryContents)
{
if (file.IsDirectory || !CanParseFile(file))
{
continue;
}
using (var stream = file.CreateReadStream())
{
var fileContent = Utf8Helper.ReadStringFromStream(stream);
var dictionary = CreateDictionary(fileContent);
if (Dictionaries.ContainsKey(dictionary.CultureName))
{
throw new AbpException($"{file.PhysicalPath} dictionary has a culture name '{dictionary.CultureName}' which is already defined!");
}
Dictionaries[dictionary.CultureName] = dictionary;
}
}
}
protected abstract bool CanParseFile(IFileInfo file);
protected abstract ILocalizationDictionary CreateDictionary(string fileContent);
}
}

1
src/Volo.Abp.VirtualFileSystem/Volo.Abp.VirtualFileSystem.csproj

@ -14,6 +14,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.FileProviders.Composite" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Physical" Version="2.0.0" />
</ItemGroup>

5
src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/Embedded/EmbeddedFileSet.cs

@ -19,7 +19,10 @@ namespace Volo.Abp.VirtualFileSystem.Embedded
[CanBeNull]
public string BaseFolderInProject { get; }
public EmbeddedFileSet([NotNull] Assembly assembly, [CanBeNull] string baseNamespace, [CanBeNull] string baseFolderInProject = null)
public EmbeddedFileSet(
[NotNull] Assembly assembly,
[CanBeNull] string baseNamespace,
[CanBeNull] string baseFolderInProject = null)
{
Check.NotNull(assembly, nameof(assembly));

125
src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileProvider.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
@ -9,80 +10,126 @@ namespace Volo.Abp.VirtualFileSystem
{
public class VirtualFileProvider : IVirtualFileProvider, ISingletonDependency
{
private readonly IFileProvider _fileProvider;
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
);
_fileProvider = CreateHybridProvider();
}
public IFileInfo GetFileInfo(string subpath)
{
if (string.IsNullOrEmpty(subpath))
{
return new NotFoundFileInfo(subpath);
}
return _fileProvider.GetFileInfo(subpath);
}
public IDirectoryContents GetDirectoryContents(string subpath)
{
return _fileProvider.GetDirectoryContents(subpath);
}
public IChangeToken Watch(string filter)
{
return _fileProvider.Watch(filter);
}
var file = _files.Value.GetOrDefault(VirtualFilePathHelper.NormalizePath(subpath));
private IFileProvider CreateHybridProvider()
{
IFileProvider fileProvider = new InternalVirtualFileProvider(_options);
if (file == null)
if (_options.FileSets.PhysicalPaths.Any())
{
return new NotFoundFileInfo(subpath);
var fileProviders = _options.FileSets.PhysicalPaths
.Select(p => new PhysicalFileProvider(p))
.Cast<IFileProvider>()
.ToList();
fileProviders.Add(fileProvider);
fileProvider = new CompositeFileProvider(fileProviders);
}
return file;
return fileProvider;
}
public IDirectoryContents GetDirectoryContents(string subpath)
private class InternalVirtualFileProvider : IFileProvider
{
var directory = GetFileInfo(subpath);
if (!directory.IsDirectory)
private readonly VirtualFileSystemOptions _options;
private readonly Lazy<Dictionary<string, IFileInfo>> _files;
public InternalVirtualFileProvider(VirtualFileSystemOptions options)
{
return new NotFoundDirectoryContents();
_options = options;
_files = new Lazy<Dictionary<string, IFileInfo>>(
CreateResourcesDictionary,
true
);
}
var fileList = new List<IFileInfo>();
var directoryPath = subpath + "/";
foreach (var fileInfo in _files.Value.Values)
public IFileInfo GetFileInfo(string subpath)
{
if (!fileInfo.PhysicalPath.StartsWith(directoryPath))
if (string.IsNullOrEmpty(subpath))
{
continue;
return new NotFoundFileInfo(subpath);
}
var relativePath = fileInfo.PhysicalPath.Substring(directoryPath.Length);
if (relativePath.Contains("/"))
var file = _files.Value.GetOrDefault(VirtualFilePathHelper.NormalizePath(subpath));
if (file == null)
{
continue;
return new NotFoundFileInfo(subpath);
}
fileList.Add(fileInfo);
return file;
}
return new EnumerableDirectoryContents(fileList);
}
public IDirectoryContents GetDirectoryContents(string subpath)
{
var directory = GetFileInfo(subpath);
if (!directory.IsDirectory)
{
return new NotFoundDirectoryContents();
}
public IChangeToken Watch(string filter)
{
return NullChangeToken.Singleton;
}
var fileList = new List<IFileInfo>();
private Dictionary<string, IFileInfo> CreateResourcesDictionary()
{
var files = new Dictionary<string, IFileInfo>(StringComparer.OrdinalIgnoreCase);
var directoryPath = subpath.EnsureEndsWith('/');
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);
}
foreach (var set in _options.FileSets)
public IChangeToken Watch(string filter)
{
set.AddFiles(files);
return NullChangeToken.Singleton;
}
return files;
private Dictionary<string, IFileInfo> CreateResourcesDictionary()
{
var files = new Dictionary<string, IFileInfo>(StringComparer.OrdinalIgnoreCase);
foreach (var set in _options.FileSets)
{
set.AddFiles(files);
}
return files;
}
}
}
}

5
src/Volo.Abp.VirtualFileSystem/Volo/Abp/VirtualFileSystem/VirtualFileSetListExtensions.cs

@ -8,14 +8,15 @@ namespace Volo.Abp.VirtualFileSystem
{
public static class VirtualFileSetListExtensions
{
public static void AddEmbedded<T>([NotNull] this VirtualFileSetList list, [CanBeNull] string baseNamespace = null)
public static void AddEmbedded<T>([NotNull] this VirtualFileSetList list, [CanBeNull] string baseNamespace = null, string baseFolderInProject = null)
{
Check.NotNull(list, nameof(list));
list.Add(
new EmbeddedFileSet(
typeof(T).Assembly,
baseNamespace
baseNamespace,
baseFolderInProject
)
);
}

21
test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs

@ -2,12 +2,12 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Shouldly;
using Volo.Abp.Localization.Base.CountryNames;
using Volo.Abp.Localization.Base.Validation;
using Volo.Abp.Localization.Source;
using Volo.Abp.Localization.SourceExt;
using Volo.Abp.Localization.TestResources.Base.CountryNames;
using Volo.Abp.Localization.TestResources.Base.Validation;
using Volo.Abp.Localization.TestResources.Source;
using Volo.Abp.Modularity;
using Volo.Abp.TestBase;
using Volo.Abp.VirtualFileSystem;
using Xunit;
namespace Volo.Abp.Localization
@ -109,12 +109,17 @@ namespace Volo.Abp.Localization
{
public override void ConfigureServices(IServiceCollection services)
{
services.Configure<VirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<TestModule>();
});
services.Configure<AbpLocalizationOptions>(options =>
{
options.Resources.AddJson<LocalizationTestValidationResource>("en");
options.Resources.AddJson<LocalizationTestCountryNamesResource>("en");
options.Resources.AddJson<LocalizationTestResource>("en");
options.Resources.ExtendWithJson<LocalizationTestResource, LocalizationTestResourceExt>();
options.Resources.AddVirtualJson<LocalizationTestValidationResource>("en", "/Volo/Abp/Localization/TestResources/Base/Validation");
options.Resources.AddVirtualJson<LocalizationTestCountryNamesResource>("en", "/Volo/Abp/Localization/TestResources/Base/CountryNames");
options.Resources.AddVirtualJson<LocalizationTestResource>("en", "/Volo/Abp/Localization/TestResources/Source");
options.Resources.ExtendWithVirtualJson<LocalizationTestResource>("/Volo/Abp/Localization/TestResources/SourceExt");
});
}
}

7
test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/SourceExt/SourceExt.cs

@ -1,7 +0,0 @@
namespace Volo.Abp.Localization.SourceExt
{
internal sealed class LocalizationTestResourceExt
{
}
}

2
test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/Base/CountryNames/LocalizationTestCountryNamesResource.cs → test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/LocalizationTestCountryNamesResource.cs

@ -1,4 +1,4 @@
namespace Volo.Abp.Localization.Base.CountryNames
namespace Volo.Abp.Localization.TestResources.Base.CountryNames
{
public sealed class LocalizationTestCountryNamesResource
{

0
test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/Base/CountryNames/en.json → test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/en.json

0
test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/Base/CountryNames/tr.json → test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/tr.json

2
test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/Base/Validation/LocalizationTestValidationResource.cs → test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/LocalizationTestValidationResource.cs

@ -1,4 +1,4 @@
namespace Volo.Abp.Localization.Base.Validation
namespace Volo.Abp.Localization.TestResources.Base.Validation
{
public sealed class LocalizationTestValidationResource
{

0
test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/Base/Validation/en.json → test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/en.json

6
test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/Source/LocalizationTestResource.cs → test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/LocalizationTestResource.cs

@ -1,7 +1,7 @@
using Volo.Abp.Localization.Base.CountryNames;
using Volo.Abp.Localization.Base.Validation;
using Volo.Abp.Localization.TestResources.Base.CountryNames;
using Volo.Abp.Localization.TestResources.Base.Validation;
namespace Volo.Abp.Localization.Source
namespace Volo.Abp.Localization.TestResources.Source
{
[InheritResource(typeof(LocalizationTestValidationResource))]
[InheritResource(typeof(LocalizationTestCountryNamesResource))]

0
test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/Source/en.json → test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/en.json

0
test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/Source/tr.json → test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/tr.json

0
test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/SourceExt/en.json → test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/en.json

0
test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/SourceExt/it.json → test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/it.json

Loading…
Cancel
Save