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 System.Collections.Generic;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Localization;
using Volo.Abp.ObjectExtending; using Volo.Abp.ObjectExtending;
using Volo.Abp.Reflection; using Volo.Abp.Reflection;
@ -58,7 +59,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending
Type = TypeHelper.GetFullNameHandlingNullableAndGenerics(propertyConfig.Type), Type = TypeHelper.GetFullNameHandlingNullableAndGenerics(propertyConfig.Type),
TypeSimple = TypeHelper.GetSimplifiedName(propertyConfig.Type), TypeSimple = TypeHelper.GetSimplifiedName(propertyConfig.Type),
Attributes = new List<ModuleObjectExtraPropertyAttributeDto>(), Attributes = new List<ModuleObjectExtraPropertyAttributeDto>(),
DisplayName = LocalizedDisplayNameDto.CreateOrNull(propertyConfig.DisplayName), DisplayName = CreateDisplayNameDto(propertyConfig),
Ui = new ModuleObjectExtraPropertyUiExtensionDto Ui = new ModuleObjectExtraPropertyUiExtensionDto
{ {
CreateForm = new ModuleObjectExtraPropertyUiFormExtensionDto CreateForm = new ModuleObjectExtraPropertyUiFormExtensionDto
@ -88,5 +89,34 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending
return objectExtensionsDto; 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;
using System.Collections.Generic; using System.Collections.Generic;
using JetBrains.Annotations;
namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending
{ {
@ -10,7 +11,8 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending
public string TypeSimple { get; set; } public string TypeSimple { get; set; }
public LocalizedDisplayNameDto DisplayName { get; set; } [CanBeNull]
public LocalizableStringDto DisplayName { get; set; }
public ModuleObjectExtraPropertyUiExtensionDto Ui { get; set; } public ModuleObjectExtraPropertyUiExtensionDto Ui { get; set; }

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

@ -1,6 +1,6 @@
namespace Microsoft.Extensions.Localization namespace Microsoft.Extensions.Localization
{ {
public static class AbpStringLocalizerFactoryExtensions public static class AbpCoreStringLocalizerFactoryExtensions
{ {
public static IStringLocalizer Create<TResource>(this IStringLocalizerFactory localizerFactory) 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 namespace Volo.Abp.Localization
{ {
public class AbpStringLocalizerFactory : IStringLocalizerFactory public class AbpStringLocalizerFactory : IStringLocalizerFactory, IAbpStringLocalizerFactoryWithDefaultResourceSupport
{ {
private readonly ResourceManagerStringLocalizerFactory _innerFactory; protected internal AbpLocalizationOptions AbpLocalizationOptions { get; }
private readonly AbpLocalizationOptions _abpLocalizationOptions; protected ResourceManagerStringLocalizerFactory InnerFactory { get; }
private readonly IServiceProvider _serviceProvider; protected IServiceProvider ServiceProvider { get; }
protected ConcurrentDictionary<Type, StringLocalizerCacheItem> LocalizerCache { get; }
private readonly ConcurrentDictionary<Type, StringLocalizerCacheItem> _localizerCache;
//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(
@ -23,29 +22,29 @@ namespace Volo.Abp.Localization
IOptions<AbpLocalizationOptions> abpLocalizationOptions, IOptions<AbpLocalizationOptions> abpLocalizationOptions,
IServiceProvider serviceProvider) IServiceProvider serviceProvider)
{ {
_innerFactory = innerFactory; InnerFactory = innerFactory;
_serviceProvider = serviceProvider; ServiceProvider = serviceProvider;
_abpLocalizationOptions = abpLocalizationOptions.Value; AbpLocalizationOptions = abpLocalizationOptions.Value;
_localizerCache = new ConcurrentDictionary<Type, StringLocalizerCacheItem>(); LocalizerCache = new ConcurrentDictionary<Type, StringLocalizerCacheItem>();
} }
public virtual IStringLocalizer Create(Type resourceType) public virtual IStringLocalizer Create(Type resourceType)
{ {
var resource = _abpLocalizationOptions.Resources.GetOrDefault(resourceType); var resource = AbpLocalizationOptions.Resources.GetOrDefault(resourceType);
if (resource == null) 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; return cacheItem.Localizer;
} }
lock (_localizerCache) lock (LocalizerCache)
{ {
return _localizerCache.GetOrAdd( return LocalizerCache.GetOrAdd(
resourceType, resourceType,
_ => CreateStringLocalizerCacheItem(resource) _ => CreateStringLocalizerCacheItem(resource)
).Localizer; ).Localizer;
@ -54,12 +53,12 @@ namespace Volo.Abp.Localization
private StringLocalizerCacheItem CreateStringLocalizerCacheItem(LocalizationResource resource) private StringLocalizerCacheItem CreateStringLocalizerCacheItem(LocalizationResource resource)
{ {
foreach (var globalContributor in _abpLocalizationOptions.GlobalContributors) foreach (var globalContributor in AbpLocalizationOptions.GlobalContributors)
{ {
resource.Contributors.Add((ILocalizationResourceContributor) Activator.CreateInstance(globalContributor)); resource.Contributors.Add((ILocalizationResourceContributor) Activator.CreateInstance(globalContributor));
} }
using (var scope = _serviceProvider.CreateScope()) using (var scope = ServiceProvider.CreateScope())
{ {
var context = new LocalizationResourceInitializationContext(resource, scope.ServiceProvider); var context = new LocalizationResourceInitializationContext(resource, scope.ServiceProvider);
@ -81,7 +80,7 @@ namespace Volo.Abp.Localization
{ {
//TODO: Investigate when this is called? //TODO: Investigate when this is called?
return _innerFactory.Create(baseName, location); return InnerFactory.Create(baseName, location);
} }
internal static void Replace(IServiceCollection services) internal static void Replace(IServiceCollection services)
@ -90,7 +89,7 @@ namespace Volo.Abp.Localization
services.AddSingleton<ResourceManagerStringLocalizerFactory>(); services.AddSingleton<ResourceManagerStringLocalizerFactory>();
} }
private class StringLocalizerCacheItem protected class StringLocalizerCacheItem
{ {
public AbpDictionaryBasedStringLocalizer Localizer { get; } public AbpDictionaryBasedStringLocalizer Localizer { get; }
@ -99,5 +98,15 @@ namespace Volo.Abp.Localization
Localizer = localizer; Localizer = localizer;
} }
} }
public IStringLocalizer CreateDefaultOrNull()
{
if (AbpLocalizationOptions.DefaultResourceType == null)
{
return null;
}
return Create(AbpLocalizationOptions.DefaultResourceType);
}
} }
} }

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

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using JetBrains.Annotations; using JetBrains.Annotations;
using Microsoft.Extensions.Localization;
using Volo.Abp.Localization; using Volo.Abp.Localization;
namespace Volo.Abp.ObjectExtending namespace Volo.Abp.ObjectExtending
@ -27,17 +28,8 @@ namespace Volo.Abp.ObjectExtending
[NotNull] [NotNull]
public List<Action<ObjectExtensionPropertyValidationContext>> Validators { get; } public List<Action<ObjectExtensionPropertyValidationContext>> Validators { get; }
[NotNull] [CanBeNull]
public ILocalizableString DisplayName public ILocalizableString DisplayName { get; set; }
{
get => _displayName;
set
{
Check.NotNull(value, nameof(value));
_displayName = value;
}
}
private ILocalizableString _displayName;
/// <summary> /// <summary>
/// Indicates whether to check the other side of the object mapping /// 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)); Type = Check.NotNull(type, nameof(type));
Name = Check.NotNull(name, nameof(name)); Name = Check.NotNull(name, nameof(name));
DisplayName = new FixedLocalizableString(Name);
Configuration = new Dictionary<object, object>(); Configuration = new Dictionary<object, object>();
ValidationAttributes = new List<ValidationAttribute>(); ValidationAttributes = new List<ValidationAttribute>();
Attributes = new List<Attribute>(); Attributes = new List<Attribute>();
Validators = new List<Action<ObjectExtensionPropertyValidationContext>>(); 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.values = {};
abp.localization.localize = function (key, sourceName) { abp.localization.localize = function (key, sourceName) {
if (sourceName === '_') { //A convention to suppress the localization
return key;
}
sourceName = sourceName || abp.localization.defaultResourceName; 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]; var source = abp.localization.values[sourceName];
if (!source) { if (!source) {
abp.log.warn('Could not find localization source: ' + sourceName); abp.log.warn('Could not find localization source: ' + sourceName);
return key; return key;
@ -97,6 +104,29 @@ var abp = abp || {};
return abp.utils.formatString.apply(this, copiedArguments); 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) { abp.localization.getResource = function (name) {
return function () { return function () {
var copiedArguments = Array.prototype.slice.call(arguments, 0); var copiedArguments = Array.prototype.slice.call(arguments, 0);

Loading…
Cancel
Save