diff --git a/src/Microsoft.Framework.Localization/IResourceNamesCache.cs b/src/Microsoft.Framework.Localization/IResourceNamesCache.cs
new file mode 100644
index 0000000000..60b7c825cc
--- /dev/null
+++ b/src/Microsoft.Framework.Localization/IResourceNamesCache.cs
@@ -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
+{
+ ///
+ /// Represents a cache of string names in resources.
+ ///
+ public interface IResourceNamesCache
+ {
+ ///
+ /// Adds a set of resource names to the cache by using the specified function, if the name does not already exist.
+ ///
+ /// The resource name to add string names for.
+ /// The function used to generate the string names for the resource.
+ /// The string names for the resource.
+ IList GetOrAdd(string name, Func> valueFactory);
+ }
+}
diff --git a/src/Microsoft.Framework.Localization/ResourceManagerStringLocalizer.cs b/src/Microsoft.Framework.Localization/ResourceManagerStringLocalizer.cs
index e8b684599c..ee62f3db03 100644
--- a/src/Microsoft.Framework.Localization/ResourceManagerStringLocalizer.cs
+++ b/src/Microsoft.Framework.Localization/ResourceManagerStringLocalizer.cs
@@ -18,12 +18,10 @@ namespace Microsoft.Framework.Localization
///
public class ResourceManagerStringLocalizer : IStringLocalizer
{
- private static readonly ConcurrentDictionary> _resourceNamesCache =
- new ConcurrentDictionary>();
-
private readonly ConcurrentDictionary _missingManifestCache =
new ConcurrentDictionary();
+ private readonly IResourceNamesCache _resourceNamesCache;
private readonly ResourceManager _resourceManager;
private readonly AssemblyWrapper _resourceAssemblyWrapper;
private readonly string _resourceBaseName;
@@ -34,11 +32,13 @@ namespace Microsoft.Framework.Localization
/// The to read strings from.
/// The that contains the strings as embedded resources.
/// The base name of the embedded resource in the that contains the strings.
+ /// Cache of the list of strings for a given resource assembly name.
public ResourceManagerStringLocalizer(
[NotNull] ResourceManager resourceManager,
[NotNull] Assembly resourceAssembly,
- [NotNull] string baseName)
- : this(resourceManager, new AssemblyWrapper(resourceAssembly), baseName)
+ [NotNull] string baseName,
+ [NotNull] IResourceNamesCache resourceNamesCache)
+ : this(resourceManager, new AssemblyWrapper(resourceAssembly), baseName, resourceNamesCache)
{
}
@@ -49,11 +49,13 @@ namespace Microsoft.Framework.Localization
public ResourceManagerStringLocalizer(
[NotNull] ResourceManager resourceManager,
[NotNull] AssemblyWrapper resourceAssemblyWrapper,
- [NotNull] string baseName)
+ [NotNull] string baseName,
+ [NotNull] IResourceNamesCache resourceNamesCache)
{
_resourceAssemblyWrapper = resourceAssemblyWrapper;
_resourceManager = resourceManager;
_resourceBaseName = baseName;
+ _resourceNamesCache = resourceNamesCache;
}
///
@@ -85,10 +87,16 @@ namespace Microsoft.Framework.Localization
public IStringLocalizer WithCulture(CultureInfo culture)
{
return culture == null
- ? new ResourceManagerStringLocalizer(_resourceManager, _resourceAssemblyWrapper, _resourceBaseName)
- : new ResourceManagerWithCultureStringLocalizer(_resourceManager,
- _resourceAssemblyWrapper,
+ ? new ResourceManagerStringLocalizer(
+ _resourceManager,
+ _resourceAssemblyWrapper.Assembly,
_resourceBaseName,
+ _resourceNamesCache)
+ : new ResourceManagerWithCultureStringLocalizer(
+ _resourceManager,
+ _resourceAssemblyWrapper.Assembly,
+ _resourceBaseName,
+ _resourceNamesCache,
culture);
}
@@ -143,9 +151,6 @@ namespace Microsoft.Framework.Localization
}
}
- // Internal to allow testing
- internal static void ClearResourceNamesCache() => _resourceNamesCache.Clear();
-
private IEnumerable GetResourceNamesFromCultureHierarchy(CultureInfo startingCulture)
{
var currentCulture = startingCulture;
diff --git a/src/Microsoft.Framework.Localization/ResourceManagerStringLocalizerFactory.cs b/src/Microsoft.Framework.Localization/ResourceManagerStringLocalizerFactory.cs
index 92899e15a4..d0ebe781a1 100644
--- a/src/Microsoft.Framework.Localization/ResourceManagerStringLocalizerFactory.cs
+++ b/src/Microsoft.Framework.Localization/ResourceManagerStringLocalizerFactory.cs
@@ -5,7 +5,6 @@ using System;
using System.Reflection;
using System.Resources;
using Microsoft.Framework.Internal;
-using Microsoft.Framework.Localization.Internal;
using Microsoft.Framework.Runtime;
namespace Microsoft.Framework.Localization
@@ -15,6 +14,8 @@ namespace Microsoft.Framework.Localization
///
public class ResourceManagerStringLocalizerFactory : IStringLocalizerFactory
{
+ private readonly IResourceNamesCache _resourceNamesCache = new ResourceNamesCache();
+
private readonly IApplicationEnvironment _applicationEnvironment;
///
@@ -35,9 +36,13 @@ namespace Microsoft.Framework.Localization
public IStringLocalizer Create([NotNull] Type resourceSource)
{
var typeInfo = resourceSource.GetTypeInfo();
- var assembly = new AssemblyWrapper(typeInfo.Assembly);
+ var assembly = typeInfo.Assembly;
var baseName = typeInfo.FullName;
- return new ResourceManagerStringLocalizer(new ResourceManager(resourceSource), assembly, baseName);
+ return new ResourceManagerStringLocalizer(
+ new ResourceManager(resourceSource),
+ assembly,
+ baseName,
+ _resourceNamesCache);
}
///
@@ -52,8 +57,9 @@ namespace Microsoft.Framework.Localization
return new ResourceManagerStringLocalizer(
new ResourceManager(baseName, assembly),
- new AssemblyWrapper(assembly),
- baseName);
+ assembly,
+ baseName,
+ _resourceNamesCache);
}
}
}
\ No newline at end of file
diff --git a/src/Microsoft.Framework.Localization/ResourceManagerWithCultureStringLocalizer.cs b/src/Microsoft.Framework.Localization/ResourceManagerWithCultureStringLocalizer.cs
index a451b10dbc..bc79cf838b 100644
--- a/src/Microsoft.Framework.Localization/ResourceManagerWithCultureStringLocalizer.cs
+++ b/src/Microsoft.Framework.Localization/ResourceManagerWithCultureStringLocalizer.cs
@@ -6,7 +6,6 @@ using System.Globalization;
using System.Reflection;
using System.Resources;
using Microsoft.Framework.Internal;
-using Microsoft.Framework.Localization.Internal;
namespace Microsoft.Framework.Localization
{
@@ -24,26 +23,15 @@ namespace Microsoft.Framework.Localization
/// The to read strings from.
/// The that contains the strings as embedded resources.
/// The base name of the embedded resource in the that contains the strings.
+ /// Cache of the list of strings for a given resource assembly name.
/// The specific to use.
public ResourceManagerWithCultureStringLocalizer(
[NotNull] ResourceManager resourceManager,
- [NotNull] Assembly assembly,
+ [NotNull] Assembly resourceAssembly,
[NotNull] string baseName,
+ [NotNull] IResourceNamesCache resourceNamesCache,
[NotNull] CultureInfo culture)
- : base(resourceManager, assembly, baseName)
- {
- _culture = culture;
- }
-
- ///
- /// Intended for testing purposes only.
- ///
- public ResourceManagerWithCultureStringLocalizer(
- [NotNull] ResourceManager resourceManager,
- [NotNull] AssemblyWrapper assemblyWrapper,
- [NotNull] string baseName,
- [NotNull] CultureInfo culture)
- : base(resourceManager, assemblyWrapper, baseName)
+ : base(resourceManager, resourceAssembly, baseName, resourceNamesCache)
{
_culture = culture;
}
diff --git a/src/Microsoft.Framework.Localization/ResourceNamesCache.cs b/src/Microsoft.Framework.Localization/ResourceNamesCache.cs
new file mode 100644
index 0000000000..27ba70cf95
--- /dev/null
+++ b/src/Microsoft.Framework.Localization/ResourceNamesCache.cs
@@ -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
+{
+ ///
+ /// An implementation of backed by a .
+ ///
+ public class ResourceNamesCache : IResourceNamesCache
+ {
+ private readonly ConcurrentDictionary> _cache = new ConcurrentDictionary>();
+
+ ///
+ public IList GetOrAdd(string name, Func> valueFactory)
+ {
+ return _cache.GetOrAdd(name, valueFactory);
+ }
+ }
+}
diff --git a/test/Microsoft.Framework.Localization.Test/ResourceManagerStringLocalizerTest.cs b/test/Microsoft.Framework.Localization.Test/ResourceManagerStringLocalizerTest.cs
index 410fc2c50f..92191c0bf8 100644
--- a/test/Microsoft.Framework.Localization.Test/ResourceManagerStringLocalizerTest.cs
+++ b/test/Microsoft.Framework.Localization.Test/ResourceManagerStringLocalizerTest.cs
@@ -17,12 +17,12 @@ namespace Microsoft.Framework.Localization.Test
public void EnumeratorCachesCultureWalkForSameAssembly()
{
// Arrange
- ResourceManagerStringLocalizer.ClearResourceNamesCache();
+ var resourceNamesCache = new ResourceNamesCache();
var baseName = "test";
var resourceAssembly = new TestAssemblyWrapper();
var resourceManager = new TestResourceManager(baseName, resourceAssembly.Assembly);
- var localizer1 = new ResourceManagerStringLocalizer(resourceManager, resourceAssembly, baseName);
- var localizer2 = new ResourceManagerStringLocalizer(resourceManager, resourceAssembly, baseName);
+ var localizer1 = new ResourceManagerStringLocalizer(resourceManager, resourceAssembly, baseName, resourceNamesCache);
+ var localizer2 = new ResourceManagerStringLocalizer(resourceManager, resourceAssembly, baseName, resourceNamesCache);
// Act
for (int i = 0; i < 5; i++)
@@ -40,14 +40,14 @@ namespace Microsoft.Framework.Localization.Test
public void EnumeratorCacheIsScopedByAssembly()
{
// Arrange
- ResourceManagerStringLocalizer.ClearResourceNamesCache();
+ var resourceNamesCache = new ResourceNamesCache();
var baseName = "test";
var resourceAssembly1 = new TestAssemblyWrapper("Assembly1");
var resourceAssembly2 = new TestAssemblyWrapper("Assembly2");
var resourceManager1 = new TestResourceManager(baseName, resourceAssembly1.Assembly);
var resourceManager2 = new TestResourceManager(baseName, resourceAssembly2.Assembly);
- var localizer1 = new ResourceManagerStringLocalizer(resourceManager1, resourceAssembly1, baseName);
- var localizer2 = new ResourceManagerStringLocalizer(resourceManager2, resourceAssembly2, baseName);
+ var localizer1 = new ResourceManagerStringLocalizer(resourceManager1, resourceAssembly1, baseName, resourceNamesCache);
+ var localizer2 = new ResourceManagerStringLocalizer(resourceManager2, resourceAssembly2, baseName, resourceNamesCache);
// Act
localizer1.ToList();