Browse Source

Localization revised

pull/279/head
Halil İbrahim Kalkan 8 years ago
parent
commit
469eb58078
  1. 26
      docs/Localization.md
  2. 9
      src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationBuilder.cs
  3. 4
      src/Volo.Abp.Localization/Volo/Abp/Localization/AbpDictionaryBasedStringLocalizer.cs
  4. 4
      src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationModule.cs
  5. 16
      src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizationDictionaryProvider.cs
  6. 12
      src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizationResourceContributor.cs
  7. 47
      src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationDictionaryProviderBase.cs
  8. 65
      src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResource.cs
  9. 18
      src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceContributorBase.cs
  10. 29
      src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceDictionary.cs
  11. 80
      src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceExtensions.cs
  12. 5
      src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceInitializationContext.cs
  13. 77
      src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceListExtensions.cs
  14. 28
      src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceNameAttribute.cs
  15. 2
      src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpValidation/AbpValidationResource.cs
  16. 14
      src/Volo.Abp.Localization/Volo/Abp/Localization/ShortLocalizationResourceNameAttribute.cs
  17. 8
      src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/Json/JsonVirtualFileLocalizationResourceContributor.cs
  18. 25
      src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/VirtualFileLocalizationResourceContributorBase.cs
  19. 2
      src/Volo.Abp.UI/Localization/Resources/AbpUi/AbpUiResource.cs
  20. 10
      src/Volo.Abp.UI/Volo/Abp/Ui/AbpUiModule.cs
  21. 8
      test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs

26
docs/Localization.md

@ -53,10 +53,9 @@ public class MyModule : AbpModule
services.Configure<AbpLocalizationOptions>(options =>
{
options.Resources.AddVirtualJson<TestResource>(
"en",
"/Localization/Resources/Test"
);
options.Resources
.Add<TestResource>("en")
.AddVirtualJson("/Localization/Resources/Test");
});
}
}
@ -64,6 +63,7 @@ public class MyModule : AbpModule
In this example;
* Added a new localization resource with "en" (English) as the default culture.
* Used JSON files to store the localization strings.
* JSON files are embedded into the assembly using the [virtual file system](Virtual-File-System.md).
@ -90,7 +90,7 @@ A JSON localization file content is shown below:
Localization resources are also available in the client (JavaScript) side. So, setting a short name for the localization resource makes it easy to use localization texts. Example:
````C#
[ShortLocalizationResourceName("Test")]
[LocalizationResourceName("Test")]
public class TestResource
{
}
@ -114,10 +114,10 @@ Alternative inheritance by configuring the `AbpLocalizationOptions`:
````C#
services.Configure<AbpLocalizationOptions>(options =>
{
options.Resources.AddVirtualJson<TestResource>("en", "/Localization/Resources/Test");
//Inherit from an existing resource
options.Resources.AddBaseTypes<TestResource>(typeof(AbpValidationResource));
options.Resources
.Add<TestResource>("en") //Define the resource by "en" default culture
.AddVirtualJson("/Localization/Resources/Test") //Add strings from virtual json files
.AddBaseTypes(typeof(AbpValidationResource)); //Inherit from an existing resource
});
````
@ -131,13 +131,13 @@ Inheriting from a resource creates a new resource without modifying the existing
````C#
services.Configure<AbpLocalizationOptions>(options =>
{
options.Resources.ExtendWithVirtualJson<TestResource>(
"/Localization/Resources/Test/Extensions"
);
options.Resources
.Get<TestResource>()
.AddVirtualJson("/Localization/Resources/Test/Extensions");
});
````
If an extension file defines the same localized string, it overrides the string.
* If an extension file defines the same localized string, it overrides the string.
#### Getting Localized Texts

9
src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationBuilder.cs

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
@ -74,12 +73,8 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
dictionary[localizedString.Name] = localizedString.Value;
}
var resourceShortName = resource.ResourceType
.GetCustomAttributes(true)
.OfType<ShortLocalizationResourceNameAttribute>()
.FirstOrDefault()?.Name ?? resource.ResourceType.FullName;
localizationConfig.Values[resourceShortName] = dictionary;
var resourceName = LocalizationResourceNameAttribute.GetName(resource.ResourceType);
localizationConfig.Values[resourceName] = dictionary;
}
return localizationConfig;

4
src/Volo.Abp.Localization/Volo/Abp/Localization/AbpDictionaryBasedStringLocalizer.cs

@ -72,7 +72,7 @@ namespace Volo.Abp.Localization
protected virtual LocalizedString GetLocalizedStringOrNull(string name, string cultureName, bool tryDefaults = true)
{
var dictionaries = Resource.DictionaryProvider.Dictionaries;
var dictionaries = Resource.Dictionaries;
//Try to get from original dictionary (with country code)
if (dictionaries.TryGetValue(cultureName, out var originalDictionary))
@ -124,7 +124,7 @@ namespace Volo.Abp.Localization
{
//TODO: Can be optimized (example: if it's already default dictionary, skip overriding)
var dictionaries = Resource.DictionaryProvider.Dictionaries;
var dictionaries = Resource.Dictionaries;
var allStrings = new Dictionary<string, LocalizedString>();

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

@ -19,7 +19,9 @@ namespace Volo.Abp.Localization
services.Configure<AbpLocalizationOptions>(options =>
{
options.Resources.AddVirtualJson<AbpValidationResource>("en", "/Localization/Resources/AbpValidation");
options.Resources
.Add<AbpValidationResource>("en")
.AddVirtualJson("/Localization/Resources/AbpValidation");
});
services.AddAssemblyOf<AbpLocalizationModule>();

16
src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizationDictionaryProvider.cs

@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
namespace Volo.Abp.Localization
{
public interface ILocalizationDictionaryProvider
{
IDictionary<string, ILocalizationDictionary> Dictionaries { get; }
event EventHandler Updated;
void Initialize(LocalizationResourceInitializationContext context);
void Extend(ILocalizationDictionaryProvider dictionaryProvider);
}
}

12
src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizationResourceContributor.cs

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
namespace Volo.Abp.Localization
{
public interface ILocalizationResourceContributor
{
event EventHandler Updated;
List<ILocalizationDictionary> GetDictionaries(LocalizationResourceInitializationContext context);
}
}

47
src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationDictionaryProviderBase.cs

@ -1,47 +0,0 @@
using System;
using System.Collections.Generic;
namespace Volo.Abp.Localization
{
public abstract class LocalizationDictionaryProviderBase : ILocalizationDictionaryProvider
{
public IDictionary<string, ILocalizationDictionary> Dictionaries { get; }
public event EventHandler Updated;
protected LocalizationDictionaryProviderBase()
{
Dictionaries = new Dictionary<string, ILocalizationDictionary>();
}
public virtual void Initialize(LocalizationResourceInitializationContext context)
{
}
public virtual void Extend(ILocalizationDictionaryProvider dictionaryProvider)
{
foreach (var dictionary in dictionaryProvider.Dictionaries.Values)
{
Extend(dictionary);
}
}
protected virtual void Extend(ILocalizationDictionary dictionary)
{
var existingDictionary = Dictionaries.GetOrDefault(dictionary.CultureName);
if (existingDictionary == null)
{
Dictionaries[dictionary.CultureName] = dictionary;
}
else
{
existingDictionary.Extend(dictionary);
}
}
protected virtual void OnUpdated()
{
Updated.InvokeSafely(this);
}
}
}

65
src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResource.cs

@ -10,71 +10,78 @@ namespace Volo.Abp.Localization
[NotNull]
public Type ResourceType { get; }
[NotNull]
public string ResourceName => LocalizationResourceNameAttribute.GetName(ResourceType);
[CanBeNull]
public string DefaultCultureName { get; set; }
[NotNull]
public ILocalizationDictionaryProvider DictionaryProvider { get; }
public IDictionary<string, ILocalizationDictionary> Dictionaries { get; }
[NotNull]
public List<ILocalizationDictionaryProvider> Extensions { get; }
public List<ILocalizationResourceContributor> Contributors { get; }
[NotNull]
public List<Type> BaseResourceTypes { get; }
public LocalizationResource(
[NotNull] Type resourceType,
[CanBeNull] string defaultCultureName, //TODO: defaultCultureName should be optional (and second argument) because it's not required for the LocalizationResource!
[NotNull] ILocalizationDictionaryProvider dictionaryProvider)
[CanBeNull] string defaultCultureName = null,
[CanBeNull] ILocalizationResourceContributor initialContributor = null)
{
ResourceType = Check.NotNull(resourceType, nameof(resourceType));
DictionaryProvider = Check.NotNull(dictionaryProvider, nameof(dictionaryProvider));
DefaultCultureName = defaultCultureName;
Dictionaries = new Dictionary<string, ILocalizationDictionary>();
BaseResourceTypes = new List<Type>();
Extensions = new List<ILocalizationDictionaryProvider>();
Contributors = new List<ILocalizationResourceContributor>();
if (initialContributor != null)
{
Contributors.Add(initialContributor);
}
AddBaseResourceTypes();
}
public virtual void Initialize(IServiceProvider serviceProvider)
{
//TODO: We should refactor here to create a better design!
var context = new LocalizationResourceInitializationContext(serviceProvider);
var context = new LocalizationResourceInitializationContext(this, serviceProvider);
InitializeDictionaryProvider(context);
InitializeExtensions(context);
Dictionaries.Clear();
InitializeContributors(context);
DictionaryProvider.Updated += (sender, args) =>
foreach (var contributor in Contributors)
{
InitializeExtensions(context);
};
foreach (var extension in Extensions)
{
extension.Updated += (sender, args) =>
contributor.Updated += (sender, args) =>
{
InitializeDictionaryProvider(context);
InitializeExtensions(context);
Dictionaries.Clear();
InitializeContributors(context);
};
}
}
private void InitializeExtensions(LocalizationResourceInitializationContext context)
protected virtual void InitializeContributors(LocalizationResourceInitializationContext context)
{
foreach (var extension in Extensions)
foreach (var contributor in Contributors)
{
extension.Initialize(context);
DictionaryProvider.Extend(extension);
foreach (var dictionary in contributor.GetDictionaries(context))
{
var existingDictionary = Dictionaries.GetOrDefault(dictionary.CultureName);
if (existingDictionary == null)
{
Dictionaries[dictionary.CultureName] = dictionary;
}
else
{
existingDictionary.Extend(dictionary);
}
}
}
}
private void InitializeDictionaryProvider(LocalizationResourceInitializationContext context)
{
DictionaryProvider.Initialize(context);
}
protected virtual void AddBaseResourceTypes()
{
var descriptors = ResourceType

18
src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceContributorBase.cs

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
namespace Volo.Abp.Localization
{
//TODO: Delete this class!
public abstract class LocalizationResourceContributorBase : ILocalizationResourceContributor
{
public event EventHandler Updated;
public abstract List<ILocalizationDictionary> GetDictionaries(LocalizationResourceInitializationContext context);
protected virtual void OnUpdated()
{
Updated.InvokeSafely(this);
}
}
}

29
src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceDictionary.cs

@ -1,10 +1,37 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
namespace Volo.Abp.Localization
{
public class LocalizationResourceDictionary : Dictionary<Type, LocalizationResource>
{
public LocalizationResource Add<TResouce>([CanBeNull] string defaultCultureName = null)
{
return Add(typeof(TResouce), defaultCultureName);
}
public LocalizationResource Add(Type resourceType, [CanBeNull] string defaultCultureName = null)
{
if (ContainsKey(resourceType))
{
throw new AbpException("This resource is already added before: " + resourceType.AssemblyQualifiedName);
}
return this[resourceType] = new LocalizationResource(resourceType, defaultCultureName);
}
public LocalizationResource Get<TResource>()
{
var resourceType = typeof(TResource);
var resource = this.GetOrDefault(resourceType);
if (resource == null)
{
throw new AbpException("Can not find a resource with given type: " + resourceType.AssemblyQualifiedName);
}
return resource;
}
}
}

80
src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceExtensions.cs

@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using Volo.Abp.Localization.VirtualFiles.Json;
namespace Volo.Abp.Localization
{
public static class LocalizationResourceExtensions
{
public static LocalizationResource AddVirtualJson(
[NotNull] this LocalizationResource localizationResource,
[NotNull] string virtualPath)
{
Check.NotNull(localizationResource, nameof(localizationResource));
Check.NotNull(virtualPath, nameof(virtualPath));
localizationResource.Contributors.Add(new JsonVirtualFileLocalizationResourceContributor(
virtualPath.EnsureStartsWith('/')
));
return localizationResource;
}
public static LocalizationResource AddBaseTypes(
[NotNull] this LocalizationResource localizationResource,
[NotNull] params Type[] types)
{
Check.NotNull(localizationResource, nameof(localizationResource));
Check.NotNull(types, nameof(types));
foreach (var type in types)
{
localizationResource.BaseResourceTypes.AddIfNotContains(type);
}
return localizationResource;
}
//public static LocalizationResource AddVirtualJson<TResource>(
// [NotNull] this LocalizationResourceDictionary resourceDictionary,
// [CanBeNull] string defaultCultureName,
// [NotNull] string virtualPath)
//{
// Check.NotNull(resourceDictionary, nameof(resourceDictionary));
// Check.NotNull(virtualPath, nameof(virtualPath));
// return resourceDictionary
// .Add<TResource>(defaultCultureName)
// .AddVirtualJson(virtualPath);
//}
//public static LocalizationResource ExtendWithVirtualJson<TResource>(
// [NotNull] this LocalizationResourceDictionary resourceDictionary,
// [NotNull] string virtualPath)
//{
// Check.NotNull(resourceDictionary, nameof(resourceDictionary));
// return resourceDictionary
// .Get<TResource>()
// .AddVirtualJson(virtualPath);
//}
//public static LocalizationResource AddBaseTypes<TResource>(
// [NotNull] this LocalizationResourceDictionary resourceDictionary,
// [NotNull] params Type[] types)
//{
// Check.NotNull(resourceDictionary, nameof(resourceDictionary));
// Check.NotNull(types, nameof(types));
// var localizationResource = resourceDictionary.Get<TResource>();
// foreach (var type in types)
// {
// localizationResource.BaseResourceTypes.AddIfNotContains(type);
// }
// return localizationResource;
//}
}
}

5
src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceInitializationContext.cs

@ -4,10 +4,13 @@ namespace Volo.Abp.Localization
{
public class LocalizationResourceInitializationContext
{
public LocalizationResource Resource { get; }
public IServiceProvider ServiceProvider { get; }
public LocalizationResourceInitializationContext(IServiceProvider serviceProvider)
public LocalizationResourceInitializationContext(LocalizationResource resource, IServiceProvider serviceProvider)
{
Resource = resource;
ServiceProvider = serviceProvider;
}
}

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

@ -1,77 +0,0 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using Volo.Abp.Localization.VirtualFiles.Json;
namespace Volo.Abp.Localization
{
public static class LocalizationResourceListExtensions
{
public static LocalizationResource AddVirtualJson<TResource>(
[NotNull] this LocalizationResourceDictionary resourceDictionary,
[CanBeNull] string defaultCultureName, //TODO: defaultCultureName should be optional (and second argument) because it's not required for the LocalizationResource!
[NotNull] string virtualPath)
{
Check.NotNull(resourceDictionary, nameof(resourceDictionary));
Check.NotNull(virtualPath, nameof(virtualPath));
virtualPath = virtualPath.EnsureStartsWith('/');
var resourceType = typeof(TResource);
if (resourceDictionary.ContainsKey(resourceType))
{
throw new AbpException("There is already a resource with given type: " + resourceType.AssemblyQualifiedName);
}
return resourceDictionary[resourceType] = new LocalizationResource(
resourceType,
defaultCultureName,
new JsonEmbeddedFileLocalizationDictionaryProvider(
virtualPath
)
);
}
public static void ExtendWithVirtualJson<TResource>(
[NotNull] this LocalizationResourceDictionary resourceDictionary,
[NotNull] string virtualPath)
{
Check.NotNull(resourceDictionary, nameof(resourceDictionary));
resourceDictionary.GetResource<TResource>().Extensions.Add(
new JsonEmbeddedFileLocalizationDictionaryProvider(
virtualPath
)
);
}
public static void AddBaseTypes<TResource>(
[NotNull] this LocalizationResourceDictionary resourceDictionary,
[NotNull] params Type[] types)
{
Check.NotNull(resourceDictionary, nameof(resourceDictionary));
Check.NotNull(types, nameof(types));
var resource = resourceDictionary.GetResource<TResource>();
foreach (var type in types)
{
resource.BaseResourceTypes.AddIfNotContains(type);
}
}
public static LocalizationResource GetResource<TResource>(this LocalizationResourceDictionary resourceDictionary)
{
var resourceType = typeof(TResource);
var resource = resourceDictionary.GetOrDefault(resourceType);
if (resource == null)
{
throw new AbpException("Can not find a resource with given type: " + resourceType.AssemblyQualifiedName);
}
return resource;
}
}
}

28
src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceNameAttribute.cs

@ -0,0 +1,28 @@
using System;
using System.Linq;
namespace Volo.Abp.Localization
{
public class LocalizationResourceNameAttribute : Attribute
{
public string Name { get; }
public LocalizationResourceNameAttribute(string name)
{
Name = name;
}
public static LocalizationResourceNameAttribute GetOrNull(Type resourceType)
{
return resourceType
.GetCustomAttributes(true)
.OfType<LocalizationResourceNameAttribute>()
.FirstOrDefault();
}
public static string GetName(Type resourceType)
{
return GetOrNull(resourceType)?.Name ?? resourceType.FullName;
}
}
}

2
src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpValidation/AbpValidationResource.cs

@ -2,7 +2,7 @@
{
//TODO: Move to Volo.Abp.Validation!
[ShortLocalizationResourceName("AbpValidation")]
[LocalizationResourceName("AbpValidation")]
public class AbpValidationResource
{

14
src/Volo.Abp.Localization/Volo/Abp/Localization/ShortLocalizationResourceNameAttribute.cs

@ -1,14 +0,0 @@
using System;
namespace Volo.Abp.Localization
{
public class ShortLocalizationResourceNameAttribute : Attribute
{
public string Name { get; }
public ShortLocalizationResourceNameAttribute(string name)
{
Name = name;
}
}
}

8
src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/Json/JsonEmbeddedFileLocalizationDictionaryProvider.cs → src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/Json/JsonVirtualFileLocalizationResourceContributor.cs

@ -4,9 +4,11 @@ using Volo.Abp.Localization.Json;
namespace Volo.Abp.Localization.VirtualFiles.Json
{
public class JsonEmbeddedFileLocalizationDictionaryProvider : VirtualFileLocalizationDictionaryProviderBase
//TODO: Use composition over inheritance..?
public class JsonVirtualFileLocalizationResourceContributor : VirtualFileLocalizationResourceContributorBase
{
public JsonEmbeddedFileLocalizationDictionaryProvider(string virtualPath)
public JsonVirtualFileLocalizationResourceContributor(string virtualPath)
: base(virtualPath)
{
@ -19,7 +21,7 @@ namespace Volo.Abp.Localization.VirtualFiles.Json
protected override ILocalizationDictionary CreateDictionaryFromFileContent(string jsonString)
{
return JsonLocalizationDictionaryBuilder.BuildFromJsonString(jsonString); //TODO: Use composition over inheritance!
return JsonLocalizationDictionaryBuilder.BuildFromJsonString(jsonString);
}
}
}

25
src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/VirtualFileLocalizationDictionaryProviderBase.cs → src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/VirtualFileLocalizationResourceContributorBase.cs

@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Primitives;
@ -7,38 +9,37 @@ using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.Localization.VirtualFiles
{
public abstract class VirtualFileLocalizationDictionaryProviderBase : LocalizationDictionaryProviderBase
public abstract class VirtualFileLocalizationResourceContributorBase : LocalizationResourceContributorBase
{
private readonly string _virtualPath;
private bool _subscribedForChanges;
protected VirtualFileLocalizationDictionaryProviderBase(string virtualPath)
protected VirtualFileLocalizationResourceContributorBase(string virtualPath)
{
_virtualPath = virtualPath;
}
public override void Initialize(LocalizationResourceInitializationContext context) //TODO: Extract initialization to a factory..?
public override List<ILocalizationDictionary> GetDictionaries(LocalizationResourceInitializationContext context)
{
var virtualFileProvider = context.ServiceProvider.GetRequiredService<IVirtualFileProvider>();
CreateDictionaries(virtualFileProvider);
if (!_subscribedForChanges)
{
ChangeToken.OnChange(() => virtualFileProvider.Watch(_virtualPath.EnsureEndsWith('/') + "**/*.*"), () =>
ChangeToken.OnChange(() => virtualFileProvider.Watch(_virtualPath.EnsureEndsWith('/') + "*.*"), () =>
{
CreateDictionaries(virtualFileProvider);
OnUpdated();
});
_subscribedForChanges = true;
}
return CreateDictionaries(virtualFileProvider);
}
private void CreateDictionaries(IFileProvider fileProvider)
private List<ILocalizationDictionary> CreateDictionaries(IFileProvider fileProvider)
{
Dictionaries.Clear();
var dictionaries = new Dictionary<string, ILocalizationDictionary>();
foreach (var file in fileProvider.GetDirectoryContents(_virtualPath))
{
@ -48,13 +49,15 @@ namespace Volo.Abp.Localization.VirtualFiles
}
var dictionary = CreateDictionaryFromFile(file);
if (Dictionaries.ContainsKey(dictionary.CultureName))
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;
dictionaries[dictionary.CultureName] = dictionary;
}
return dictionaries.Values.ToList();
}
protected abstract bool CanParseFile(IFileInfo file);

2
src/Volo.Abp.UI/Localization/Resources/AbpUi/AbpUiResource.cs

@ -2,7 +2,7 @@
namespace Localization.Resources.AbpUi
{
[ShortLocalizationResourceName("AbpUi")]
[LocalizationResourceName("AbpUi")]
public class AbpUiResource
{
}

10
src/Volo.Abp.UI/Volo/Abp/Ui/AbpUiModule.cs

@ -13,16 +13,16 @@ namespace Volo.Abp.UI
{
public override void ConfigureServices(IServiceCollection services)
{
services.Configure<AbpLocalizationOptions>(options =>
services.Configure<VirtualFileSystemOptions>(options =>
{
options.Resources.AddVirtualJson<AbpUiResource>("en", "/Localization/Resources/AbpUi");
options.FileSets.AddEmbedded<AbpUiModule>();
});
services.Configure<VirtualFileSystemOptions>(options =>
services.Configure<AbpLocalizationOptions>(options =>
{
options.FileSets.AddEmbedded<AbpUiModule>("");
options.Resources.Add<AbpUiResource>("en").AddVirtualJson("/Localization/Resources/AbpUi");
});
services.AddAssemblyOf<AbpUiModule>();
}
}

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

@ -117,10 +117,10 @@ namespace Volo.Abp.Localization
services.Configure<AbpLocalizationOptions>(options =>
{
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");
options.Resources.Add<LocalizationTestValidationResource>("en").AddVirtualJson("/Volo/Abp/Localization/TestResources/Base/Validation");
options.Resources.Add<LocalizationTestCountryNamesResource>("en").AddVirtualJson("/Volo/Abp/Localization/TestResources/Base/CountryNames");
options.Resources.Add<LocalizationTestResource>("en").AddVirtualJson("/Volo/Abp/Localization/TestResources/Source");
options.Resources.Get<LocalizationTestResource>().AddVirtualJson("/Volo/Abp/Localization/TestResources/SourceExt");
});
}
}

Loading…
Cancel
Save