Auto find the display name for a extra property (if not specified explicitly).

pull/3831/head
Halil İbrahim Kalkan 6 years ago
parent 52b6c10a55
commit 7e10bd92ce

@ -1,5 +1,6 @@
using System.Collections.Generic;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Localization;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Reflection;
@ -58,7 +59,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending
Type = TypeHelper.GetFullNameHandlingNullableAndGenerics(propertyConfig.Type),
TypeSimple = TypeHelper.GetSimplifiedName(propertyConfig.Type),
Attributes = new List<ModuleObjectExtraPropertyAttributeDto>(),
DisplayName = LocalizedDisplayNameDto.CreateOrNull(propertyConfig.DisplayName),
DisplayName = CreateDisplayNameDto(propertyConfig),
Ui = new ModuleObjectExtraPropertyUiExtensionDto
{
CreateForm = new ModuleObjectExtraPropertyUiFormExtensionDto
@ -88,5 +89,34 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending
return objectExtensionsDto;
}
private static LocalizableStringDto CreateDisplayNameDto(
ModuleEntityObjectPropertyExtensionConfiguration propertyConfig)
{
if (propertyConfig.DisplayName == null)
{
return null;
}
if (propertyConfig.DisplayName is LocalizableString localizableStringInstance)
{
return new LocalizableStringDto
{
Name = localizableStringInstance.Name,
Resource = LocalizationResourceNameAttribute.GetName(localizableStringInstance.ResourceType)
};
}
if (propertyConfig.DisplayName is FixedLocalizableString fixedLocalizableString)
{
return new LocalizableStringDto
{
Name = fixedLocalizableString.Value,
Resource = "_"
};
}
return null;
}
}
}

@ -0,0 +1,14 @@
using System;
using JetBrains.Annotations;
namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending
{
[Serializable]
public class LocalizableStringDto
{
public string Name { get; set; }
[CanBeNull]
public string Resource { get; set; }
}
}

@ -1,37 +0,0 @@
using System;
using JetBrains.Annotations;
using Volo.Abp.Localization;
namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending
{
[Serializable]
public class LocalizedDisplayNameDto
{
public string Name { get; set; }
public string Resource { get; set; }
[CanBeNull]
public static LocalizedDisplayNameDto CreateOrNull(ILocalizableString localizableString)
{
if (localizableString is LocalizableString localizableStringInstance)
{
return new LocalizedDisplayNameDto
{
Name = localizableStringInstance.Name,
Resource = LocalizationResourceNameAttribute.GetName(localizableStringInstance.ResourceType)
};
}
if (localizableString is FixedLocalizableString fixedLocalizableString)
{
return new LocalizedDisplayNameDto
{
Name = fixedLocalizableString.Value,
};
}
return null;
}
}
}

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending
{
@ -10,7 +11,8 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending
public string TypeSimple { get; set; }
public LocalizedDisplayNameDto DisplayName { get; set; }
[CanBeNull]
public LocalizableStringDto DisplayName { get; set; }
public ModuleObjectExtraPropertyUiExtensionDto Ui { get; set; }

@ -103,7 +103,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ViewFeatures
if (modelExplorer.Metadata is DefaultModelMetadata metadata)
{
metadata.DisplayMetadata.DisplayName =
() => extensionPropertyInfo.DisplayName.Localize(_stringLocalizerFactory);
() => extensionPropertyInfo.GetDisplayName(_stringLocalizerFactory);
}
foreach (var validationAttribute in extensionPropertyInfo.GetValidationAttributes())

@ -1,6 +1,6 @@
namespace Microsoft.Extensions.Localization
{
public static class AbpStringLocalizerFactoryExtensions
public static class AbpCoreStringLocalizerFactoryExtensions
{
public static IStringLocalizer Create<TResource>(this IStringLocalizerFactory localizerFactory)
{

@ -0,0 +1,11 @@
namespace Microsoft.Extensions.Localization
{
public static class AbpStringLocalizerFactoryExtensions
{
public static IStringLocalizer CreateDefaultOrNull(this IStringLocalizerFactory localizerFactory)
{
return (localizerFactory as IAbpStringLocalizerFactoryWithDefaultResourceSupport)
?.CreateDefaultOrNull();
}
}
}

@ -0,0 +1,10 @@
using JetBrains.Annotations;
namespace Microsoft.Extensions.Localization
{
public interface IAbpStringLocalizerFactoryWithDefaultResourceSupport
{
[CanBeNull]
IStringLocalizer CreateDefaultOrNull();
}
}

@ -9,13 +9,12 @@ using Microsoft.Extensions.Options;
namespace Volo.Abp.Localization
{
public class AbpStringLocalizerFactory : IStringLocalizerFactory
public class AbpStringLocalizerFactory : IStringLocalizerFactory, IAbpStringLocalizerFactoryWithDefaultResourceSupport
{
private readonly ResourceManagerStringLocalizerFactory _innerFactory;
private readonly AbpLocalizationOptions _abpLocalizationOptions;
private readonly IServiceProvider _serviceProvider;
private readonly ConcurrentDictionary<Type, StringLocalizerCacheItem> _localizerCache;
protected internal AbpLocalizationOptions AbpLocalizationOptions { get; }
protected ResourceManagerStringLocalizerFactory InnerFactory { get; }
protected IServiceProvider ServiceProvider { get; }
protected ConcurrentDictionary<Type, StringLocalizerCacheItem> LocalizerCache { get; }
//TODO: It's better to use decorator pattern for IStringLocalizerFactory instead of getting ResourceManagerStringLocalizerFactory as a dependency.
public AbpStringLocalizerFactory(
@ -23,29 +22,29 @@ namespace Volo.Abp.Localization
IOptions<AbpLocalizationOptions> abpLocalizationOptions,
IServiceProvider serviceProvider)
{
_innerFactory = innerFactory;
_serviceProvider = serviceProvider;
_abpLocalizationOptions = abpLocalizationOptions.Value;
InnerFactory = innerFactory;
ServiceProvider = serviceProvider;
AbpLocalizationOptions = abpLocalizationOptions.Value;
_localizerCache = new ConcurrentDictionary<Type, StringLocalizerCacheItem>();
LocalizerCache = new ConcurrentDictionary<Type, StringLocalizerCacheItem>();
}
public virtual IStringLocalizer Create(Type resourceType)
{
var resource = _abpLocalizationOptions.Resources.GetOrDefault(resourceType);
var resource = AbpLocalizationOptions.Resources.GetOrDefault(resourceType);
if (resource == null)
{
return _innerFactory.Create(resourceType);
return InnerFactory.Create(resourceType);
}
if (_localizerCache.TryGetValue(resourceType, out var cacheItem))
if (LocalizerCache.TryGetValue(resourceType, out var cacheItem))
{
return cacheItem.Localizer;
}
lock (_localizerCache)
lock (LocalizerCache)
{
return _localizerCache.GetOrAdd(
return LocalizerCache.GetOrAdd(
resourceType,
_ => CreateStringLocalizerCacheItem(resource)
).Localizer;
@ -54,12 +53,12 @@ namespace Volo.Abp.Localization
private StringLocalizerCacheItem CreateStringLocalizerCacheItem(LocalizationResource resource)
{
foreach (var globalContributor in _abpLocalizationOptions.GlobalContributors)
foreach (var globalContributor in AbpLocalizationOptions.GlobalContributors)
{
resource.Contributors.Add((ILocalizationResourceContributor) Activator.CreateInstance(globalContributor));
}
using (var scope = _serviceProvider.CreateScope())
using (var scope = ServiceProvider.CreateScope())
{
var context = new LocalizationResourceInitializationContext(resource, scope.ServiceProvider);
@ -81,7 +80,7 @@ namespace Volo.Abp.Localization
{
//TODO: Investigate when this is called?
return _innerFactory.Create(baseName, location);
return InnerFactory.Create(baseName, location);
}
internal static void Replace(IServiceCollection services)
@ -90,7 +89,7 @@ namespace Volo.Abp.Localization
services.AddSingleton<ResourceManagerStringLocalizerFactory>();
}
private class StringLocalizerCacheItem
protected class StringLocalizerCacheItem
{
public AbpDictionaryBasedStringLocalizer Localizer { get; }
@ -99,5 +98,15 @@ namespace Volo.Abp.Localization
Localizer = localizer;
}
}
public IStringLocalizer CreateDefaultOrNull()
{
if (AbpLocalizationOptions.DefaultResourceType == null)
{
return null;
}
return Create(AbpLocalizationOptions.DefaultResourceType);
}
}
}

@ -22,17 +22,8 @@ namespace Volo.Abp.ObjectExtending
[NotNull]
public List<Action<ObjectExtensionPropertyValidationContext>> Validators { get; }
[NotNull]
public ILocalizableString DisplayName
{
get => _displayName;
set
{
Check.NotNull(value, nameof(value));
_displayName = value;
}
}
private ILocalizableString _displayName;
[CanBeNull]
public ILocalizableString DisplayName { get; set; }
[NotNull]
public Dictionary<object, object> Configuration { get; }
@ -49,8 +40,6 @@ namespace Volo.Abp.ObjectExtending
Type = Check.NotNull(type, nameof(type));
Name = Check.NotNull(name, nameof(name));
DisplayName = new FixedLocalizableString(Name);
Configuration = new Dictionary<object, object>();
Attributes = new List<Attribute>();
Validators = new List<Action<ObjectExtensionPropertyValidationContext>>();

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using JetBrains.Annotations;
using Microsoft.Extensions.Localization;
using Volo.Abp.Localization;
namespace Volo.Abp.ObjectExtending
@ -27,17 +28,8 @@ namespace Volo.Abp.ObjectExtending
[NotNull]
public List<Action<ObjectExtensionPropertyValidationContext>> Validators { get; }
[NotNull]
public ILocalizableString DisplayName
{
get => _displayName;
set
{
Check.NotNull(value, nameof(value));
_displayName = value;
}
}
private ILocalizableString _displayName;
[CanBeNull]
public ILocalizableString DisplayName { get; set; }
/// <summary>
/// Indicates whether to check the other side of the object mapping
@ -65,12 +57,40 @@ namespace Volo.Abp.ObjectExtending
Type = Check.NotNull(type, nameof(type));
Name = Check.NotNull(name, nameof(name));
DisplayName = new FixedLocalizableString(Name);
Configuration = new Dictionary<object, object>();
ValidationAttributes = new List<ValidationAttribute>();
Attributes = new List<Attribute>();
Validators = new List<Action<ObjectExtensionPropertyValidationContext>>();
}
[NotNull]
public string GetDisplayName(
[NotNull] IStringLocalizerFactory stringLocalizerFactory)
{
if (DisplayName != null)
{
return DisplayName.Localize(stringLocalizerFactory);
}
var defaultStringLocalizer = stringLocalizerFactory.CreateDefaultOrNull();
if (defaultStringLocalizer == null)
{
return Name;
}
var localizedString = defaultStringLocalizer[$"DisplayName:{Name}"];
if (!localizedString.ResourceNotFound)
{
return localizedString;
}
localizedString = defaultStringLocalizer[Name];
if (!localizedString.ResourceNotFound)
{
return localizedString;
}
return Name;
}
}
}

@ -76,10 +76,17 @@ var abp = abp || {};
abp.localization.values = {};
abp.localization.localize = function (key, sourceName) {
if (sourceName === '_') { //A convention to suppress the localization
return key;
}
sourceName = sourceName || abp.localization.defaultResourceName;
if (!sourceName) {
abp.log.warn('Localization source name is not specified and the defaultResourceName was not defined!');
return key;
}
var source = abp.localization.values[sourceName];
if (!source) {
abp.log.warn('Could not find localization source: ' + sourceName);
return key;
@ -97,6 +104,29 @@ var abp = abp || {};
return abp.utils.formatString.apply(this, copiedArguments);
};
abp.localization.isLocalized = function (key, sourceName) {
if (sourceName === '_') { //A convention to suppress the localization
return true;
}
sourceName = sourceName || abp.localization.defaultResourceName;
if (!sourceName) {
return false;
}
var source = abp.localization.values[sourceName];
if (!source) {
return false;
}
var value = source[key];
if (value === undefined) {
return false;
}
return true;
};
abp.localization.getResource = function (name) {
return function () {
var copiedArguments = Array.prototype.slice.call(arguments, 0);

Loading…
Cancel
Save