Browse Source

Allow to work with non-typed localization resources

pull/13845/head
Halil İbrahim Kalkan 4 years ago
parent
commit
560ba6fce3
  1. 13
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs
  2. 4
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpLocalizationScriptController.cs
  3. 2
      framework/src/Volo.Abp.Core/System/AbpObjectExtensions.cs
  4. 6
      framework/src/Volo.Abp.Localization.Abstractions/Microsoft/Extensions/Localization/AbpStringLocalizerFactoryExtensions.cs
  5. 54
      framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/LocalizableString.cs
  6. 5
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpDictionaryBasedStringLocalizer.cs
  7. 41
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpStringLocalizerFactory.cs
  8. 9
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/IExternalLocalizationStore.cs
  9. 12
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizableStringSerializer.cs
  10. 28
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResource.cs
  11. 25
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceBase.cs
  12. 5
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceDictionary.cs
  13. 30
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceExtensions.cs
  14. 11
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/NullExternalLocalizationStore.cs
  15. 10
      framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfigurationExtensions.cs
  16. 1
      framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpStringLocalizerFactory_Tests.cs
  17. 2
      framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/LocalizableStringSerializer_Tests.cs

13
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs

@ -218,14 +218,13 @@ public class AbpApplicationConfigurationAppService : ApplicationService, IAbpApp
foreach (var resource in _localizationOptions.Resources.Values) foreach (var resource in _localizationOptions.Resources.Values)
{ {
var dictionary = new Dictionary<string, string>(); var dictionary = new Dictionary<string, string>();
var localizer = StringLocalizerFactory.CreateByResourceNameOrNull(resource.ResourceName);
var localizer = (IStringLocalizer) _serviceProvider.GetRequiredService( if (localizer != null)
typeof(IStringLocalizer<>).MakeGenericType(resource.ResourceType)
);
foreach (var localizedString in localizer.GetAllStrings())
{ {
dictionary[localizedString.Name] = localizedString.Value; foreach (var localizedString in localizer.GetAllStrings())
{
dictionary[localizedString.Name] = localizedString.Value;
}
} }
localizationConfig.Values[resource.ResourceName] = dictionary; localizationConfig.Values[resource.ResourceName] = dictionary;

4
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpLocalizationScriptController.cs

@ -34,8 +34,8 @@ public class AbpLocalizationScriptController
{ {
foreach (var resource in LocalizationOptions.Resources.Values) foreach (var resource in LocalizationOptions.Resources.Values)
{ {
var localizer = StringLocalizerFactory.Create(resource.ResourceType); var localizer = StringLocalizerFactory.CreateByResourceNameOrNull(resource.ResourceName);
localizer.GetAllStrings(); localizer?.GetAllStrings();
} }
} }
} }

2
framework/src/Volo.Abp.Core/System/AbpObjectExtensions.cs

@ -3,6 +3,7 @@ using System.ComponentModel;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
namespace System; namespace System;
@ -17,6 +18,7 @@ public static class AbpObjectExtensions
/// <typeparam name="T">Type to be casted</typeparam> /// <typeparam name="T">Type to be casted</typeparam>
/// <param name="obj">Object to cast</param> /// <param name="obj">Object to cast</param>
/// <returns>Casted object</returns> /// <returns>Casted object</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T As<T>(this object obj) public static T As<T>(this object obj)
where T : class where T : class
{ {

6
framework/src/Volo.Abp.Localization.Abstractions/Microsoft/Extensions/Localization/AbpStringLocalizerFactoryExtensions.cs

@ -1,15 +1,18 @@
using Volo.Abp; using JetBrains.Annotations;
using Volo.Abp;
namespace Microsoft.Extensions.Localization; namespace Microsoft.Extensions.Localization;
public static class AbpStringLocalizerFactoryExtensions public static class AbpStringLocalizerFactoryExtensions
{ {
[CanBeNull]
public static IStringLocalizer CreateDefaultOrNull(this IStringLocalizerFactory localizerFactory) public static IStringLocalizer CreateDefaultOrNull(this IStringLocalizerFactory localizerFactory)
{ {
return (localizerFactory as IAbpStringLocalizerFactory) return (localizerFactory as IAbpStringLocalizerFactory)
?.CreateDefaultOrNull(); ?.CreateDefaultOrNull();
} }
[CanBeNull]
public static IStringLocalizer CreateByResourceNameOrNull( public static IStringLocalizer CreateByResourceNameOrNull(
this IStringLocalizerFactory localizerFactory, this IStringLocalizerFactory localizerFactory,
string resourceName) string resourceName)
@ -18,6 +21,7 @@ public static class AbpStringLocalizerFactoryExtensions
?.CreateByResourceNameOrNull(resourceName); ?.CreateByResourceNameOrNull(resourceName);
} }
[NotNull]
public static IStringLocalizer CreateByResourceName( public static IStringLocalizer CreateByResourceName(
this IStringLocalizerFactory localizerFactory, this IStringLocalizerFactory localizerFactory,
string resourceName) string resourceName)

54
framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/LocalizableString.cs

@ -6,6 +6,9 @@ namespace Volo.Abp.Localization;
public class LocalizableString : ILocalizableString public class LocalizableString : ILocalizableString
{ {
[CanBeNull]
public string ResourceName { get; }
[CanBeNull] [CanBeNull]
public Type ResourceType { get; } public Type ResourceType { get; }
@ -16,22 +19,30 @@ public class LocalizableString : ILocalizableString
{ {
Name = Check.NotNullOrEmpty(name, nameof(name)); Name = Check.NotNullOrEmpty(name, nameof(name));
ResourceType = resourceType; ResourceType = resourceType;
if (resourceType != null)
{
ResourceName = LocalizationResourceNameAttribute.GetName(resourceType);
}
} }
public LocalizedString Localize(IStringLocalizerFactory stringLocalizerFactory) public LocalizableString([NotNull] string name, [CanBeNull] string resourceName = null)
{ {
var localizer = ResourceType != null Name = Check.NotNullOrEmpty(name, nameof(name));
? stringLocalizerFactory.Create(ResourceType) ResourceName = resourceName;
: stringLocalizerFactory.CreateDefaultOrNull(); }
public LocalizedString Localize(IStringLocalizerFactory stringLocalizerFactory)
{
var localizer = CreateStringLocalizerOrNull(stringLocalizerFactory);
if (localizer == null) if (localizer == null)
{ {
throw new AbpException($"Set {nameof(ResourceType)} or configure the default localization resource type (in the AbpLocalizationOptions)!"); throw new AbpException($"Set {nameof(ResourceName)} or configure the default localization resource type (in the AbpLocalizationOptions)!");
} }
var result = localizer[Name]; var result = localizer[Name];
if (result.ResourceNotFound && ResourceType != null) if (result.ResourceNotFound && ResourceName != null)
{ {
/* Search in the default resource if not found in the provided resource */ /* Search in the default resource if not found in the provided resource */
localizer = stringLocalizerFactory.CreateDefaultOrNull(); localizer = stringLocalizerFactory.CreateDefaultOrNull();
@ -44,8 +55,37 @@ public class LocalizableString : ILocalizableString
return result; return result;
} }
private IStringLocalizer CreateStringLocalizerOrNull(IStringLocalizerFactory stringLocalizerFactory)
{
if (ResourceType != null)
{
return stringLocalizerFactory.Create(ResourceType);
}
if (ResourceName != null)
{
var localizerByName = stringLocalizerFactory.CreateByResourceNameOrNull(ResourceName);
if (localizerByName != null)
{
return localizerByName;
}
}
return stringLocalizerFactory.CreateDefaultOrNull();
}
public static LocalizableString Create<TResource>([NotNull] string name) public static LocalizableString Create<TResource>([NotNull] string name)
{ {
return new LocalizableString(typeof(TResource), name); return Create(typeof(TResource), name);
}
public static LocalizableString Create(Type resourceType,[NotNull] string name)
{
return new LocalizableString(resourceType, name);
}
public static LocalizableString Create([NotNull] string name, [CanBeNull] string resourceName = null)
{
return new LocalizableString(name, resourceName);
} }
} }

5
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpDictionaryBasedStringLocalizer.cs

@ -20,7 +20,10 @@ public class AbpDictionaryBasedStringLocalizer : IStringLocalizer, IStringLocali
public virtual LocalizedString this[string name, params object[] arguments] => GetLocalizedStringFormatted(name, arguments); public virtual LocalizedString this[string name, params object[] arguments] => GetLocalizedStringFormatted(name, arguments);
public AbpDictionaryBasedStringLocalizer(LocalizationResource resource, List<IStringLocalizer> baseLocalizers, AbpLocalizationOptions abpLocalizationOptions) public AbpDictionaryBasedStringLocalizer(
LocalizationResource resource,
List<IStringLocalizer> baseLocalizers,
AbpLocalizationOptions abpLocalizationOptions)
{ {
Resource = resource; Resource = resource;
BaseLocalizers = baseLocalizers; BaseLocalizers = baseLocalizers;

41
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpStringLocalizerFactory.cs

@ -14,19 +14,22 @@ public class AbpStringLocalizerFactory : IStringLocalizerFactory, IAbpStringLoca
protected internal AbpLocalizationOptions AbpLocalizationOptions { get; } protected internal AbpLocalizationOptions AbpLocalizationOptions { get; }
protected ResourceManagerStringLocalizerFactory InnerFactory { get; } protected ResourceManagerStringLocalizerFactory InnerFactory { get; }
protected IServiceProvider ServiceProvider { get; } protected IServiceProvider ServiceProvider { get; }
protected ConcurrentDictionary<Type, StringLocalizerCacheItem> LocalizerCache { get; } protected IExternalLocalizationStore ExternalLocalizationStore { get; }
protected ConcurrentDictionary<string, StringLocalizerCacheItem> LocalizerCache { get; }
//TODO: It's better to use decorator pattern for IStringLocalizerFactory instead of getting ResourceManagerStringLocalizerFactory as a dependency. //TODO: It's better to use decorator pattern for IStringLocalizerFactory instead of getting ResourceManagerStringLocalizerFactory as a dependency.
public AbpStringLocalizerFactory( public AbpStringLocalizerFactory(
ResourceManagerStringLocalizerFactory innerFactory, ResourceManagerStringLocalizerFactory innerFactory,
IOptions<AbpLocalizationOptions> abpLocalizationOptions, IOptions<AbpLocalizationOptions> abpLocalizationOptions,
IServiceProvider serviceProvider) IServiceProvider serviceProvider,
IExternalLocalizationStore externalLocalizationStore)
{ {
InnerFactory = innerFactory; InnerFactory = innerFactory;
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
ExternalLocalizationStore = externalLocalizationStore;
AbpLocalizationOptions = abpLocalizationOptions.Value; AbpLocalizationOptions = abpLocalizationOptions.Value;
LocalizerCache = new ConcurrentDictionary<Type, StringLocalizerCacheItem>(); LocalizerCache = new ConcurrentDictionary<string, StringLocalizerCacheItem>();
} }
public virtual IStringLocalizer Create(Type resourceType) public virtual IStringLocalizer Create(Type resourceType)
@ -37,7 +40,7 @@ public class AbpStringLocalizerFactory : IStringLocalizerFactory, IAbpStringLoca
return InnerFactory.Create(resourceType); return InnerFactory.Create(resourceType);
} }
return CreateInternal(resourceType, resource); return CreateInternal(resource.ResourceName, resource);
} }
public IStringLocalizer CreateByResourceNameOrNull(string resourceName) public IStringLocalizer CreateByResourceNameOrNull(string resourceName)
@ -45,15 +48,19 @@ public class AbpStringLocalizerFactory : IStringLocalizerFactory, IAbpStringLoca
var resource = AbpLocalizationOptions.Resources.GetOrNull(resourceName); var resource = AbpLocalizationOptions.Resources.GetOrNull(resourceName);
if (resource == null) if (resource == null)
{ {
return null; resource = ExternalLocalizationStore.GetResourceOrNull(resourceName);
if (resource == null)
{
return null;
}
} }
return CreateInternal(resource.ResourceType, resource); return CreateInternal(resourceName, resource);
} }
private IStringLocalizer CreateInternal(Type resourceType, LocalizationResource resource) private IStringLocalizer CreateInternal(string resourceName, LocalizationResource resource)
{ {
if (LocalizerCache.TryGetValue(resourceType, out var cacheItem)) if (LocalizerCache.TryGetValue(resourceName, out var cacheItem))
{ {
return cacheItem.Localizer; return cacheItem.Localizer;
} }
@ -61,7 +68,7 @@ public class AbpStringLocalizerFactory : IStringLocalizerFactory, IAbpStringLoca
lock (LocalizerCache) lock (LocalizerCache)
{ {
return LocalizerCache.GetOrAdd( return LocalizerCache.GetOrAdd(
resourceType, resourceName,
_ => CreateStringLocalizerCacheItem(resource) _ => CreateStringLocalizerCacheItem(resource)
).Localizer; ).Localizer;
} }
@ -69,9 +76,13 @@ public class AbpStringLocalizerFactory : IStringLocalizerFactory, IAbpStringLoca
private StringLocalizerCacheItem CreateStringLocalizerCacheItem(LocalizationResource resource) private StringLocalizerCacheItem CreateStringLocalizerCacheItem(LocalizationResource resource)
{ {
foreach (var globalContributor in AbpLocalizationOptions.GlobalContributors) foreach (var globalContributorType in AbpLocalizationOptions.GlobalContributors)
{ {
resource.Contributors.Add((ILocalizationResourceContributor)Activator.CreateInstance(globalContributor)); resource.Contributors.Add(
Activator
.CreateInstance(globalContributorType)
.As<ILocalizationResourceContributor>()
);
} }
var context = new LocalizationResourceInitializationContext(resource, ServiceProvider); var context = new LocalizationResourceInitializationContext(resource, ServiceProvider);
@ -84,7 +95,11 @@ public class AbpStringLocalizerFactory : IStringLocalizerFactory, IAbpStringLoca
return new StringLocalizerCacheItem( return new StringLocalizerCacheItem(
new AbpDictionaryBasedStringLocalizer( new AbpDictionaryBasedStringLocalizer(
resource, resource,
resource.BaseResourceTypes.Select(Create).ToList(), resource
.BaseResourceNames
.Select(CreateByResourceNameOrNull)
.Where(x => x != null)
.ToList(),
AbpLocalizationOptions AbpLocalizationOptions
) )
); );
@ -122,4 +137,4 @@ public class AbpStringLocalizerFactory : IStringLocalizerFactory, IAbpStringLoca
return Create(AbpLocalizationOptions.DefaultResourceType); return Create(AbpLocalizationOptions.DefaultResourceType);
} }
} }

9
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/IExternalLocalizationStore.cs

@ -0,0 +1,9 @@
using JetBrains.Annotations;
namespace Volo.Abp.Localization;
public interface IExternalLocalizationStore
{
[CanBeNull]
LocalizationResource GetResourceOrNull([NotNull] string resourceName);
}

12
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizableStringSerializer.cs

@ -55,13 +55,13 @@ public class LocalizableStringSerializer : ILocalizableStringSerializer, ITransi
{ {
throw new AbpException("Invalid LocalizableString value: " + value); throw new AbpException("Invalid LocalizableString value: " + value);
} }
if (!LocalizationOptions.Resources.ContainsResource(resourceName))
{
resourceName = null;
}
var resourceType = LocalizationOptions.Resources.GetOrNull(resourceName)?.ResourceType; return LocalizableString.Create(name, resourceName);
return new LocalizableString(
resourceType,
name
);
default: default:
return new FixedLocalizableString(value); return new FixedLocalizableString(value);
} }

28
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResource.cs

@ -5,40 +5,26 @@ using JetBrains.Annotations;
namespace Volo.Abp.Localization; namespace Volo.Abp.Localization;
public class LocalizationResource public class LocalizationResource : LocalizationResourceBase
{ {
[NotNull] [NotNull]
public Type ResourceType { get; } private Type ResourceType { get; }
[NotNull]
public string ResourceName => LocalizationResourceNameAttribute.GetName(ResourceType);
[CanBeNull]
public string DefaultCultureName { get; set; }
[NotNull]
public LocalizationResourceContributorList Contributors { get; }
[NotNull]
public List<Type> BaseResourceTypes { get; }
public LocalizationResource( public LocalizationResource(
[NotNull] Type resourceType, [NotNull] Type resourceType,
[CanBeNull] string defaultCultureName = null, [CanBeNull] string defaultCultureName = null,
[CanBeNull] ILocalizationResourceContributor initialContributor = null) [CanBeNull] ILocalizationResourceContributor initialContributor = null)
: base(LocalizationResourceNameAttribute.GetName(resourceType))
{ {
ResourceType = Check.NotNull(resourceType, nameof(resourceType)); ResourceType = Check.NotNull(resourceType, nameof(resourceType));
DefaultCultureName = defaultCultureName; DefaultCultureName = defaultCultureName;
BaseResourceTypes = new List<Type>(); AddBaseResourceTypes();
Contributors = new LocalizationResourceContributorList();
if (initialContributor != null) if (initialContributor != null)
{ {
Contributors.Add(initialContributor); Contributors.Add(initialContributor);
} }
AddBaseResourceTypes();
} }
protected virtual void AddBaseResourceTypes() protected virtual void AddBaseResourceTypes()
@ -51,8 +37,8 @@ public class LocalizationResource
{ {
foreach (var baseResourceType in descriptor.GetInheritedResourceTypes()) foreach (var baseResourceType in descriptor.GetInheritedResourceTypes())
{ {
BaseResourceTypes.AddIfNotContains(baseResourceType); BaseResourceNames.AddIfNotContains(LocalizationResourceNameAttribute.GetName(baseResourceType));
} }
} }
} }
} }

25
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceBase.cs

@ -0,0 +1,25 @@
using System.Collections.Generic;
using JetBrains.Annotations;
namespace Volo.Abp.Localization;
public abstract class LocalizationResourceBase
{
[NotNull]
public string ResourceName { get; }
public List<string> BaseResourceNames { get; }
[CanBeNull]
public string DefaultCultureName { get; set; }
[NotNull]
public LocalizationResourceContributorList Contributors { get; }
public LocalizationResourceBase([NotNull] string resourceName)
{
ResourceName = Check.NotNullOrWhiteSpace(resourceName, nameof(resourceName));
Contributors = new LocalizationResourceContributorList();
BaseResourceNames = new();
}
}

5
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceDictionary.cs

@ -56,4 +56,9 @@ public class LocalizationResourceDictionary : Dictionary<Type, LocalizationResou
{ {
return _resourcesByNames.GetOrDefault(resourceName); return _resourcesByNames.GetOrDefault(resourceName);
} }
public bool ContainsResource(string resourceName)
{
return _resourcesByNames.ContainsKey(resourceName);
}
} }

30
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceExtensions.cs

@ -7,9 +7,10 @@ namespace Volo.Abp.Localization;
public static class LocalizationResourceExtensions public static class LocalizationResourceExtensions
{ {
public static LocalizationResource AddVirtualJson( public static TLocalizationResource AddVirtualJson<TLocalizationResource>(
[NotNull] this LocalizationResource localizationResource, [NotNull] this TLocalizationResource localizationResource,
[NotNull] string virtualPath) [NotNull] string virtualPath)
where TLocalizationResource : LocalizationResourceBase
{ {
Check.NotNull(localizationResource, nameof(localizationResource)); Check.NotNull(localizationResource, nameof(localizationResource));
Check.NotNull(virtualPath, nameof(virtualPath)); Check.NotNull(virtualPath, nameof(virtualPath));
@ -21,16 +22,35 @@ public static class LocalizationResourceExtensions
return localizationResource; return localizationResource;
} }
public static LocalizationResource AddBaseTypes( public static TLocalizationResource AddBaseTypes<TLocalizationResource>(
[NotNull] this LocalizationResource localizationResource, [NotNull] this TLocalizationResource localizationResource,
[NotNull] params Type[] types) [NotNull] params Type[] types)
where TLocalizationResource : LocalizationResourceBase
{ {
Check.NotNull(localizationResource, nameof(localizationResource)); Check.NotNull(localizationResource, nameof(localizationResource));
Check.NotNull(types, nameof(types)); Check.NotNull(types, nameof(types));
foreach (var type in types) foreach (var type in types)
{ {
localizationResource.BaseResourceTypes.AddIfNotContains(type); localizationResource
.BaseResourceNames
.AddIfNotContains(LocalizationResourceNameAttribute.GetName(type));
}
return localizationResource;
}
public static TLocalizationResource AddBaseResources<TLocalizationResource>(
[NotNull] this TLocalizationResource localizationResource,
[NotNull] params string[] baseResourceNames)
where TLocalizationResource : LocalizationResourceBase
{
Check.NotNull(localizationResource, nameof(localizationResource));
Check.NotNull(baseResourceNames, nameof(baseResourceNames));
foreach (var baseResourceName in baseResourceNames)
{
localizationResource.BaseResourceNames.AddIfNotContains(baseResourceName);
} }
return localizationResource; return localizationResource;

11
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/NullExternalLocalizationStore.cs

@ -0,0 +1,11 @@
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Localization;
public class NullExternalLocalizationStore : IExternalLocalizationStore, ISingletonDependency
{
public LocalizationResource GetResourceOrNull(string resourceName)
{
return null;
}
}

10
framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfigurationExtensions.cs

@ -8,20 +8,18 @@ public static class ExtensionPropertyConfigurationExtensions
public static string GetLocalizationResourceNameOrNull( public static string GetLocalizationResourceNameOrNull(
this ExtensionPropertyConfiguration property) this ExtensionPropertyConfiguration property)
{ {
var resourceType = property.GetLocalizationResourceTypeOrNull(); if (property.DisplayName is LocalizableString localizableString)
if (resourceType == null)
{ {
return null; return localizableString.ResourceName;
} }
return LocalizationResourceNameAttribute.GetName(resourceType); return null;
} }
public static Type GetLocalizationResourceTypeOrNull( public static Type GetLocalizationResourceTypeOrNull(
this ExtensionPropertyConfiguration property) this ExtensionPropertyConfiguration property)
{ {
if (property.DisplayName != null && if (property.DisplayName is LocalizableString localizableString)
property.DisplayName is LocalizableString localizableString)
{ {
return localizableString.ResourceType; return localizableString.ResourceType;
} }

1
framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpStringLocalizerFactory_Tests.cs

@ -32,7 +32,6 @@ public class AbpStringLocalizerFactory_Tests : AbpIntegratedTest<AbpLocalization
} }
} }
[Fact] [Fact]
public void Should_Throw_Exception_For_Unknown_Resource_Names() public void Should_Throw_Exception_For_Unknown_Resource_Names()
{ {

2
framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/LocalizableStringSerializer_Tests.cs

@ -59,7 +59,7 @@ public class LocalizableStringSerializer_Tests : AbpIntegratedTest<AbpLocalizati
var localizableString = _serializer var localizableString = _serializer
.Deserialize("L:Test,Car") .Deserialize("L:Test,Car")
.ShouldBeOfType<LocalizableString>(); .ShouldBeOfType<LocalizableString>();
localizableString.ResourceType.ShouldBe(typeof(LocalizationTestResource)); localizableString.ResourceName.ShouldBe("Test");
localizableString.Name.ShouldBe("Car"); localizableString.Name.ShouldBe("Car");
Assert.Throws<AbpException>(() => Assert.Throws<AbpException>(() =>

Loading…
Cancel
Save