Merge branch 'release' into dev
This commit is contained in:
commit
b583c46372
|
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Microsoft.Framework.Localization
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a cache of string names in resources.
|
||||||
|
/// </summary>
|
||||||
|
public interface IResourceNamesCache
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a set of resource names to the cache by using the specified function, if the name does not already exist.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The resource name to add string names for.</param>
|
||||||
|
/// <param name="valueFactory">The function used to generate the string names for the resource.</param>
|
||||||
|
/// <returns>The string names for the resource.</returns>
|
||||||
|
IList<string> GetOrAdd(string name, Func<string, IList<string>> valueFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,12 +18,10 @@ namespace Microsoft.Framework.Localization
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ResourceManagerStringLocalizer : IStringLocalizer
|
public class ResourceManagerStringLocalizer : IStringLocalizer
|
||||||
{
|
{
|
||||||
private static readonly ConcurrentDictionary<string, IList<string>> _resourceNamesCache =
|
|
||||||
new ConcurrentDictionary<string, IList<string>>();
|
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<string, object> _missingManifestCache =
|
private readonly ConcurrentDictionary<string, object> _missingManifestCache =
|
||||||
new ConcurrentDictionary<string, object>();
|
new ConcurrentDictionary<string, object>();
|
||||||
|
|
||||||
|
private readonly IResourceNamesCache _resourceNamesCache;
|
||||||
private readonly ResourceManager _resourceManager;
|
private readonly ResourceManager _resourceManager;
|
||||||
private readonly AssemblyWrapper _resourceAssemblyWrapper;
|
private readonly AssemblyWrapper _resourceAssemblyWrapper;
|
||||||
private readonly string _resourceBaseName;
|
private readonly string _resourceBaseName;
|
||||||
|
|
@ -34,11 +32,13 @@ namespace Microsoft.Framework.Localization
|
||||||
/// <param name="resourceManager">The <see cref="System.Resources.ResourceManager"/> to read strings from.</param>
|
/// <param name="resourceManager">The <see cref="System.Resources.ResourceManager"/> to read strings from.</param>
|
||||||
/// <param name="resourceAssembly">The <see cref="Assembly"/> that contains the strings as embedded resources.</param>
|
/// <param name="resourceAssembly">The <see cref="Assembly"/> that contains the strings as embedded resources.</param>
|
||||||
/// <param name="baseName">The base name of the embedded resource in the <see cref="Assembly"/> that contains the strings.</param>
|
/// <param name="baseName">The base name of the embedded resource in the <see cref="Assembly"/> that contains the strings.</param>
|
||||||
|
/// <param name="resourceNamesCache">Cache of the list of strings for a given resource assembly name.</param>
|
||||||
public ResourceManagerStringLocalizer(
|
public ResourceManagerStringLocalizer(
|
||||||
[NotNull] ResourceManager resourceManager,
|
[NotNull] ResourceManager resourceManager,
|
||||||
[NotNull] Assembly resourceAssembly,
|
[NotNull] Assembly resourceAssembly,
|
||||||
[NotNull] string baseName)
|
[NotNull] string baseName,
|
||||||
: this(resourceManager, new AssemblyWrapper(resourceAssembly), baseName)
|
[NotNull] IResourceNamesCache resourceNamesCache)
|
||||||
|
: this(resourceManager, new AssemblyWrapper(resourceAssembly), baseName, resourceNamesCache)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -49,11 +49,13 @@ namespace Microsoft.Framework.Localization
|
||||||
public ResourceManagerStringLocalizer(
|
public ResourceManagerStringLocalizer(
|
||||||
[NotNull] ResourceManager resourceManager,
|
[NotNull] ResourceManager resourceManager,
|
||||||
[NotNull] AssemblyWrapper resourceAssemblyWrapper,
|
[NotNull] AssemblyWrapper resourceAssemblyWrapper,
|
||||||
[NotNull] string baseName)
|
[NotNull] string baseName,
|
||||||
|
[NotNull] IResourceNamesCache resourceNamesCache)
|
||||||
{
|
{
|
||||||
_resourceAssemblyWrapper = resourceAssemblyWrapper;
|
_resourceAssemblyWrapper = resourceAssemblyWrapper;
|
||||||
_resourceManager = resourceManager;
|
_resourceManager = resourceManager;
|
||||||
_resourceBaseName = baseName;
|
_resourceBaseName = baseName;
|
||||||
|
_resourceNamesCache = resourceNamesCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
@ -85,10 +87,16 @@ namespace Microsoft.Framework.Localization
|
||||||
public IStringLocalizer WithCulture(CultureInfo culture)
|
public IStringLocalizer WithCulture(CultureInfo culture)
|
||||||
{
|
{
|
||||||
return culture == null
|
return culture == null
|
||||||
? new ResourceManagerStringLocalizer(_resourceManager, _resourceAssemblyWrapper, _resourceBaseName)
|
? new ResourceManagerStringLocalizer(
|
||||||
: new ResourceManagerWithCultureStringLocalizer(_resourceManager,
|
_resourceManager,
|
||||||
_resourceAssemblyWrapper,
|
_resourceAssemblyWrapper.Assembly,
|
||||||
_resourceBaseName,
|
_resourceBaseName,
|
||||||
|
_resourceNamesCache)
|
||||||
|
: new ResourceManagerWithCultureStringLocalizer(
|
||||||
|
_resourceManager,
|
||||||
|
_resourceAssemblyWrapper.Assembly,
|
||||||
|
_resourceBaseName,
|
||||||
|
_resourceNamesCache,
|
||||||
culture);
|
culture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -143,9 +151,6 @@ namespace Microsoft.Framework.Localization
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal to allow testing
|
|
||||||
internal static void ClearResourceNamesCache() => _resourceNamesCache.Clear();
|
|
||||||
|
|
||||||
private IEnumerable<string> GetResourceNamesFromCultureHierarchy(CultureInfo startingCulture)
|
private IEnumerable<string> GetResourceNamesFromCultureHierarchy(CultureInfo startingCulture)
|
||||||
{
|
{
|
||||||
var currentCulture = startingCulture;
|
var currentCulture = startingCulture;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Resources;
|
using System.Resources;
|
||||||
using Microsoft.Framework.Internal;
|
using Microsoft.Framework.Internal;
|
||||||
using Microsoft.Framework.Localization.Internal;
|
|
||||||
using Microsoft.Framework.Runtime;
|
using Microsoft.Framework.Runtime;
|
||||||
|
|
||||||
namespace Microsoft.Framework.Localization
|
namespace Microsoft.Framework.Localization
|
||||||
|
|
@ -15,6 +14,8 @@ namespace Microsoft.Framework.Localization
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ResourceManagerStringLocalizerFactory : IStringLocalizerFactory
|
public class ResourceManagerStringLocalizerFactory : IStringLocalizerFactory
|
||||||
{
|
{
|
||||||
|
private readonly IResourceNamesCache _resourceNamesCache = new ResourceNamesCache();
|
||||||
|
|
||||||
private readonly IApplicationEnvironment _applicationEnvironment;
|
private readonly IApplicationEnvironment _applicationEnvironment;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -35,9 +36,13 @@ namespace Microsoft.Framework.Localization
|
||||||
public IStringLocalizer Create([NotNull] Type resourceSource)
|
public IStringLocalizer Create([NotNull] Type resourceSource)
|
||||||
{
|
{
|
||||||
var typeInfo = resourceSource.GetTypeInfo();
|
var typeInfo = resourceSource.GetTypeInfo();
|
||||||
var assembly = new AssemblyWrapper(typeInfo.Assembly);
|
var assembly = typeInfo.Assembly;
|
||||||
var baseName = typeInfo.FullName;
|
var baseName = typeInfo.FullName;
|
||||||
return new ResourceManagerStringLocalizer(new ResourceManager(resourceSource), assembly, baseName);
|
return new ResourceManagerStringLocalizer(
|
||||||
|
new ResourceManager(resourceSource),
|
||||||
|
assembly,
|
||||||
|
baseName,
|
||||||
|
_resourceNamesCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -52,8 +57,9 @@ namespace Microsoft.Framework.Localization
|
||||||
|
|
||||||
return new ResourceManagerStringLocalizer(
|
return new ResourceManagerStringLocalizer(
|
||||||
new ResourceManager(baseName, assembly),
|
new ResourceManager(baseName, assembly),
|
||||||
new AssemblyWrapper(assembly),
|
assembly,
|
||||||
baseName);
|
baseName,
|
||||||
|
_resourceNamesCache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6,7 +6,6 @@ using System.Globalization;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Resources;
|
using System.Resources;
|
||||||
using Microsoft.Framework.Internal;
|
using Microsoft.Framework.Internal;
|
||||||
using Microsoft.Framework.Localization.Internal;
|
|
||||||
|
|
||||||
namespace Microsoft.Framework.Localization
|
namespace Microsoft.Framework.Localization
|
||||||
{
|
{
|
||||||
|
|
@ -24,26 +23,15 @@ namespace Microsoft.Framework.Localization
|
||||||
/// <param name="resourceManager">The <see cref="System.Resources.ResourceManager"/> to read strings from.</param>
|
/// <param name="resourceManager">The <see cref="System.Resources.ResourceManager"/> to read strings from.</param>
|
||||||
/// <param name="resourceAssembly">The <see cref="Assembly"/> that contains the strings as embedded resources.</param>
|
/// <param name="resourceAssembly">The <see cref="Assembly"/> that contains the strings as embedded resources.</param>
|
||||||
/// <param name="baseName">The base name of the embedded resource in the <see cref="Assembly"/> that contains the strings.</param>
|
/// <param name="baseName">The base name of the embedded resource in the <see cref="Assembly"/> that contains the strings.</param>
|
||||||
|
/// <param name="resourceNamesCache">Cache of the list of strings for a given resource assembly name.</param>
|
||||||
/// <param name="culture">The specific <see cref="CultureInfo"/> to use.</param>
|
/// <param name="culture">The specific <see cref="CultureInfo"/> to use.</param>
|
||||||
public ResourceManagerWithCultureStringLocalizer(
|
public ResourceManagerWithCultureStringLocalizer(
|
||||||
[NotNull] ResourceManager resourceManager,
|
[NotNull] ResourceManager resourceManager,
|
||||||
[NotNull] Assembly assembly,
|
[NotNull] Assembly resourceAssembly,
|
||||||
[NotNull] string baseName,
|
[NotNull] string baseName,
|
||||||
|
[NotNull] IResourceNamesCache resourceNamesCache,
|
||||||
[NotNull] CultureInfo culture)
|
[NotNull] CultureInfo culture)
|
||||||
: base(resourceManager, assembly, baseName)
|
: base(resourceManager, resourceAssembly, baseName, resourceNamesCache)
|
||||||
{
|
|
||||||
_culture = culture;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Intended for testing purposes only.
|
|
||||||
/// </summary>
|
|
||||||
public ResourceManagerWithCultureStringLocalizer(
|
|
||||||
[NotNull] ResourceManager resourceManager,
|
|
||||||
[NotNull] AssemblyWrapper assemblyWrapper,
|
|
||||||
[NotNull] string baseName,
|
|
||||||
[NotNull] CultureInfo culture)
|
|
||||||
: base(resourceManager, assemblyWrapper, baseName)
|
|
||||||
{
|
{
|
||||||
_culture = culture;
|
_culture = culture;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Microsoft.Framework.Localization
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An implementation of <see cref="IResourceNamesCache"/> backed by a <see cref="ConcurrentDictionary{TKey, TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
public class ResourceNamesCache : IResourceNamesCache
|
||||||
|
{
|
||||||
|
private readonly ConcurrentDictionary<string, IList<string>> _cache = new ConcurrentDictionary<string, IList<string>>();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IList<string> GetOrAdd(string name, Func<string, IList<string>> valueFactory)
|
||||||
|
{
|
||||||
|
return _cache.GetOrAdd(name, valueFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,12 +17,12 @@ namespace Microsoft.Framework.Localization.Test
|
||||||
public void EnumeratorCachesCultureWalkForSameAssembly()
|
public void EnumeratorCachesCultureWalkForSameAssembly()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
ResourceManagerStringLocalizer.ClearResourceNamesCache();
|
var resourceNamesCache = new ResourceNamesCache();
|
||||||
var baseName = "test";
|
var baseName = "test";
|
||||||
var resourceAssembly = new TestAssemblyWrapper();
|
var resourceAssembly = new TestAssemblyWrapper();
|
||||||
var resourceManager = new TestResourceManager(baseName, resourceAssembly.Assembly);
|
var resourceManager = new TestResourceManager(baseName, resourceAssembly.Assembly);
|
||||||
var localizer1 = new ResourceManagerStringLocalizer(resourceManager, resourceAssembly, baseName);
|
var localizer1 = new ResourceManagerStringLocalizer(resourceManager, resourceAssembly, baseName, resourceNamesCache);
|
||||||
var localizer2 = new ResourceManagerStringLocalizer(resourceManager, resourceAssembly, baseName);
|
var localizer2 = new ResourceManagerStringLocalizer(resourceManager, resourceAssembly, baseName, resourceNamesCache);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
|
|
@ -40,14 +40,14 @@ namespace Microsoft.Framework.Localization.Test
|
||||||
public void EnumeratorCacheIsScopedByAssembly()
|
public void EnumeratorCacheIsScopedByAssembly()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
ResourceManagerStringLocalizer.ClearResourceNamesCache();
|
var resourceNamesCache = new ResourceNamesCache();
|
||||||
var baseName = "test";
|
var baseName = "test";
|
||||||
var resourceAssembly1 = new TestAssemblyWrapper("Assembly1");
|
var resourceAssembly1 = new TestAssemblyWrapper("Assembly1");
|
||||||
var resourceAssembly2 = new TestAssemblyWrapper("Assembly2");
|
var resourceAssembly2 = new TestAssemblyWrapper("Assembly2");
|
||||||
var resourceManager1 = new TestResourceManager(baseName, resourceAssembly1.Assembly);
|
var resourceManager1 = new TestResourceManager(baseName, resourceAssembly1.Assembly);
|
||||||
var resourceManager2 = new TestResourceManager(baseName, resourceAssembly2.Assembly);
|
var resourceManager2 = new TestResourceManager(baseName, resourceAssembly2.Assembly);
|
||||||
var localizer1 = new ResourceManagerStringLocalizer(resourceManager1, resourceAssembly1, baseName);
|
var localizer1 = new ResourceManagerStringLocalizer(resourceManager1, resourceAssembly1, baseName, resourceNamesCache);
|
||||||
var localizer2 = new ResourceManagerStringLocalizer(resourceManager2, resourceAssembly2, baseName);
|
var localizer2 = new ResourceManagerStringLocalizer(resourceManager2, resourceAssembly2, baseName, resourceNamesCache);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
localizer1.ToList();
|
localizer1.ToList();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue