Skip to content
This repository was archived by the owner on Nov 29, 2018. It is now read-only.

Commit 39aa943

Browse files
Add location to LocalizedString and add logging (#331)
1 parent 970e2e0 commit 39aa943

10 files changed

+213
-36
lines changed

src/Microsoft.Extensions.Localization.Abstractions/LocalizedString.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,18 @@ public LocalizedString(string name, string value)
2727
/// <param name="value">The actual string.</param>
2828
/// <param name="resourceNotFound">Whether the string was not found in a resource. Set this to <c>true</c> to indicate an alternate string value was used.</param>
2929
public LocalizedString(string name, string value, bool resourceNotFound)
30+
: this(name, value, resourceNotFound, searchedLocation: null)
31+
{
32+
}
33+
34+
/// <summary>
35+
/// Creates a new <see cref="LocalizedString"/>.
36+
/// </summary>
37+
/// <param name="name">The name of the string in the resource it was loaded from.</param>
38+
/// <param name="value">The actual string.</param>
39+
/// <param name="resourceNotFound">Whether the string was not found in a resource. Set this to <c>true</c> to indicate an alternate string value was used.</param>
40+
/// <param name="searchedLocation">The location which was searched for a localization value.</param>
41+
public LocalizedString(string name, string value, bool resourceNotFound, string searchedLocation)
3042
{
3143
if (name == null)
3244
{
@@ -41,6 +53,7 @@ public LocalizedString(string name, string value, bool resourceNotFound)
4153
Name = name;
4254
Value = value;
4355
ResourceNotFound = resourceNotFound;
56+
SearchedLocation = searchedLocation;
4457
}
4558

4659
public static implicit operator string(LocalizedString localizedString)
@@ -63,6 +76,11 @@ public static implicit operator string(LocalizedString localizedString)
6376
/// </summary>
6477
public bool ResourceNotFound { get; }
6578

79+
/// <summary>
80+
/// The location which was searched for a localization value.
81+
/// </summary>
82+
public string SearchedLocation { get; }
83+
6684
/// <summary>
6785
/// Returns the actual string.
6886
/// </summary>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Globalization;
6+
using Microsoft.Extensions.Logging;
7+
8+
namespace Microsoft.Extensions.Localization.Internal
9+
{
10+
internal static class ResourceManagerStringLocalizerLoggerExtensions
11+
{
12+
private static readonly Action<ILogger, string, string, CultureInfo, Exception> _searchedLocation;
13+
14+
static ResourceManagerStringLocalizerLoggerExtensions()
15+
{
16+
_searchedLocation = LoggerMessage.Define<string, string, CultureInfo>(
17+
LogLevel.Debug,
18+
1,
19+
$"{nameof(ResourceManagerStringLocalizer)} searched for '{{Key}}' in '{{LocationSearched}}' with culture '{{Culture}}'.");
20+
}
21+
22+
public static void SearchedLocation(this ILogger logger, string key, string searchedLocation, CultureInfo culture)
23+
{
24+
_searchedLocation(logger, key, searchedLocation, culture, null);
25+
}
26+
}
27+
}

src/Microsoft.Extensions.Localization/Microsoft.Extensions.Localization.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<ProjectReference Include="..\Microsoft.Extensions.Localization.Abstractions\Microsoft.Extensions.Localization.Abstractions.csproj" />
1616
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="1.2.0-*" />
1717
<PackageReference Include="Microsoft.Extensions.Options" Version="1.2.0-*" />
18+
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="1.2.0-*" />
1819
</ItemGroup>
1920

2021
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">

src/Microsoft.Extensions.Localization/ResourceManagerStringLocalizer.cs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Reflection;
99
using System.Resources;
1010
using Microsoft.Extensions.Localization.Internal;
11+
using Microsoft.Extensions.Logging;
1112

1213
namespace Microsoft.Extensions.Localization
1314
{
@@ -23,6 +24,7 @@ public class ResourceManagerStringLocalizer : IStringLocalizer
2324
private readonly ResourceManager _resourceManager;
2425
private readonly IResourceStringProvider _resourceStringProvider;
2526
private readonly string _resourceBaseName;
27+
private readonly ILogger _logger;
2628

2729
/// <summary>
2830
/// Creates a new <see cref="ResourceManagerStringLocalizer"/>.
@@ -31,16 +33,19 @@ public class ResourceManagerStringLocalizer : IStringLocalizer
3133
/// <param name="resourceAssembly">The <see cref="Assembly"/> that contains the strings as embedded resources.</param>
3234
/// <param name="baseName">The base name of the embedded resource that contains the strings.</param>
3335
/// <param name="resourceNamesCache">Cache of the list of strings for a given resource assembly name.</param>
36+
/// <param name="logger">The <see cref="ILogger"/>.</param>
3437
public ResourceManagerStringLocalizer(
3538
ResourceManager resourceManager,
3639
Assembly resourceAssembly,
3740
string baseName,
38-
IResourceNamesCache resourceNamesCache)
41+
IResourceNamesCache resourceNamesCache,
42+
ILogger logger)
3943
: this(
4044
resourceManager,
4145
new AssemblyWrapper(resourceAssembly),
4246
baseName,
43-
resourceNamesCache)
47+
resourceNamesCache,
48+
logger)
4449
{
4550
}
4651

@@ -51,12 +56,14 @@ public ResourceManagerStringLocalizer(
5156
ResourceManager resourceManager,
5257
AssemblyWrapper resourceAssemblyWrapper,
5358
string baseName,
54-
IResourceNamesCache resourceNamesCache)
59+
IResourceNamesCache resourceNamesCache,
60+
ILogger logger)
5561
: this(
5662
resourceManager,
5763
new AssemblyResourceStringProvider(resourceNamesCache, resourceAssemblyWrapper, baseName),
5864
baseName,
59-
resourceNamesCache)
65+
resourceNamesCache,
66+
logger)
6067
{
6168
}
6269

@@ -67,7 +74,8 @@ public ResourceManagerStringLocalizer(
6774
ResourceManager resourceManager,
6875
IResourceStringProvider resourceStringProvider,
6976
string baseName,
70-
IResourceNamesCache resourceNamesCache)
77+
IResourceNamesCache resourceNamesCache,
78+
ILogger logger)
7179
{
7280
if (resourceManager == null)
7381
{
@@ -89,10 +97,16 @@ public ResourceManagerStringLocalizer(
8997
throw new ArgumentNullException(nameof(resourceNamesCache));
9098
}
9199

100+
if (logger == null)
101+
{
102+
throw new ArgumentNullException(nameof(logger));
103+
}
104+
92105
_resourceStringProvider = resourceStringProvider;
93106
_resourceManager = resourceManager;
94107
_resourceBaseName = baseName;
95108
_resourceNamesCache = resourceNamesCache;
109+
_logger = logger;
96110
}
97111

98112
/// <inheritdoc />
@@ -107,7 +121,7 @@ public virtual LocalizedString this[string name]
107121

108122
var value = GetStringSafely(name, null);
109123

110-
return new LocalizedString(name, value ?? name, resourceNotFound: value == null);
124+
return new LocalizedString(name, value ?? name, resourceNotFound: value == null, searchedLocation: _resourceBaseName);
111125
}
112126
}
113127

@@ -124,7 +138,7 @@ public virtual LocalizedString this[string name]
124138
var format = GetStringSafely(name, null);
125139
var value = string.Format(format ?? name, arguments);
126140

127-
return new LocalizedString(name, value, resourceNotFound: format == null);
141+
return new LocalizedString(name, value, resourceNotFound: format == null, searchedLocation: _resourceBaseName);
128142
}
129143
}
130144

@@ -140,13 +154,15 @@ public IStringLocalizer WithCulture(CultureInfo culture)
140154
_resourceManager,
141155
_resourceStringProvider,
142156
_resourceBaseName,
143-
_resourceNamesCache)
157+
_resourceNamesCache,
158+
_logger)
144159
: new ResourceManagerWithCultureStringLocalizer(
145160
_resourceManager,
146161
_resourceStringProvider,
147162
_resourceBaseName,
148163
_resourceNamesCache,
149-
culture);
164+
culture,
165+
_logger);
150166
}
151167

152168
/// <inheritdoc />
@@ -173,7 +189,7 @@ protected IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures,
173189
foreach (var name in resourceNames)
174190
{
175191
var value = GetStringSafely(name, culture);
176-
yield return new LocalizedString(name, value ?? name, resourceNotFound: value == null);
192+
yield return new LocalizedString(name, value ?? name, resourceNotFound: value == null, searchedLocation: _resourceBaseName);
177193
}
178194
}
179195

@@ -191,7 +207,11 @@ protected string GetStringSafely(string name, CultureInfo culture)
191207
throw new ArgumentNullException(nameof(name));
192208
}
193209

194-
var cacheKey = $"name={name}&culture={(culture ?? CultureInfo.CurrentUICulture).Name}";
210+
var keyCulture = culture ?? CultureInfo.CurrentUICulture;
211+
212+
var cacheKey = $"name={name}&culture={keyCulture.Name}";
213+
214+
_logger.SearchedLocation(name, _resourceBaseName, keyCulture);
195215

196216
if (_missingManifestCache.ContainsKey(cacheKey))
197217
{

src/Microsoft.Extensions.Localization/ResourceManagerStringLocalizerFactory.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.IO;
77
using System.Reflection;
88
using System.Resources;
9+
using Microsoft.Extensions.Logging;
910
using Microsoft.Extensions.Options;
1011

1112
namespace Microsoft.Extensions.Localization
@@ -24,20 +25,30 @@ public class ResourceManagerStringLocalizerFactory : IStringLocalizerFactory
2425
private readonly ConcurrentDictionary<string, ResourceManagerStringLocalizer> _localizerCache =
2526
new ConcurrentDictionary<string, ResourceManagerStringLocalizer>();
2627
private readonly string _resourcesRelativePath;
28+
private readonly ILoggerFactory _loggerFactory;
2729

2830
/// <summary>
2931
/// Creates a new <see cref="ResourceManagerStringLocalizer"/>.
3032
/// </summary>
3133
/// <param name="localizationOptions">The <see cref="IOptions{LocalizationOptions}"/>.</param>
34+
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
3235
public ResourceManagerStringLocalizerFactory(
33-
IOptions<LocalizationOptions> localizationOptions)
36+
IOptions<LocalizationOptions> localizationOptions,
37+
ILoggerFactory loggerFactory)
3438
{
3539
if (localizationOptions == null)
3640
{
3741
throw new ArgumentNullException(nameof(localizationOptions));
3842
}
3943

44+
if (loggerFactory == null)
45+
{
46+
throw new ArgumentNullException(nameof(loggerFactory));
47+
}
48+
4049
_resourcesRelativePath = localizationOptions.Value.ResourcesPath ?? string.Empty;
50+
_loggerFactory = loggerFactory;
51+
4152
if (!string.IsNullOrEmpty(_resourcesRelativePath))
4253
{
4354
_resourcesRelativePath = _resourcesRelativePath.Replace(Path.AltDirectorySeparatorChar, '.')
@@ -180,7 +191,8 @@ protected virtual ResourceManagerStringLocalizer CreateResourceManagerStringLoca
180191
new ResourceManager(baseName, assembly),
181192
assembly,
182193
baseName,
183-
_resourceNamesCache);
194+
_resourceNamesCache,
195+
_loggerFactory.CreateLogger<ResourceManagerStringLocalizer>());
184196
}
185197

186198
/// <summary>

src/Microsoft.Extensions.Localization/ResourceManagerWithCultureStringLocalizer.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Reflection;
88
using System.Resources;
99
using Microsoft.Extensions.Localization.Internal;
10+
using Microsoft.Extensions.Logging;
1011

1112
namespace Microsoft.Extensions.Localization
1213
{
@@ -26,13 +27,15 @@ public class ResourceManagerWithCultureStringLocalizer : ResourceManagerStringLo
2627
/// <param name="baseName">The base name of the embedded resource that contains the strings.</param>
2728
/// <param name="resourceNamesCache">Cache of the list of strings for a given resource assembly name.</param>
2829
/// <param name="culture">The specific <see cref="CultureInfo"/> to use.</param>
30+
/// <param name="logger">The <see cref="ILogger"/>.</param>
2931
internal ResourceManagerWithCultureStringLocalizer(
3032
ResourceManager resourceManager,
3133
IResourceStringProvider resourceStringProvider,
3234
string baseName,
3335
IResourceNamesCache resourceNamesCache,
34-
CultureInfo culture)
35-
: base(resourceManager, resourceStringProvider, baseName, resourceNamesCache)
36+
CultureInfo culture,
37+
ILogger logger)
38+
: base(resourceManager, resourceStringProvider, baseName, resourceNamesCache, logger)
3639
{
3740
if (resourceManager == null)
3841
{
@@ -70,13 +73,15 @@ internal ResourceManagerWithCultureStringLocalizer(
7073
/// <param name="baseName">The base name of the embedded resource that contains the strings.</param>
7174
/// <param name="resourceNamesCache">Cache of the list of strings for a given resource assembly name.</param>
7275
/// <param name="culture">The specific <see cref="CultureInfo"/> to use.</param>
76+
/// <param name="logger">The <see cref="ILogger"/>.</param>
7377
public ResourceManagerWithCultureStringLocalizer(
7478
ResourceManager resourceManager,
7579
Assembly resourceAssembly,
7680
string baseName,
7781
IResourceNamesCache resourceNamesCache,
78-
CultureInfo culture)
79-
: base(resourceManager, resourceAssembly, baseName, resourceNamesCache)
82+
CultureInfo culture,
83+
ILogger logger)
84+
: base(resourceManager, resourceAssembly, baseName, resourceNamesCache, logger)
8085
{
8186
if (resourceManager == null)
8287
{

test/Microsoft.AspNetCore.Localization.Tests/Microsoft.AspNetCore.Localization.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<ItemGroup>
1111
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Localization\Microsoft.AspNetCore.Localization.csproj" />
1212
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="1.2.0-*" />
13+
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.2.0-*" />
1314
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-*" />
1415
<PackageReference Include="xunit" Version="2.2.0-*" />
1516
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0-*" />

test/Microsoft.Extensions.Localization.Tests/Microsoft.Extensions.Localization.Tests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99

1010
<ItemGroup>
1111
<ProjectReference Include="..\..\src\Microsoft.Extensions.Localization\Microsoft.Extensions.Localization.csproj" />
12+
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="1.2.0-*" />
1213
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="1.2.0-*" />
14+
<PackageReference Include="Microsoft.Extensions.Logging.Testing" Version="1.2.0-*" />
1315
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-*" />
1416
<PackageReference Include="Moq" Version="4.6.36-*" />
1517
<PackageReference Include="xunit" Version="2.2.0-*" />

0 commit comments

Comments
 (0)