diff --git a/src/My.Extensions.Localization.Json/Caching/IResourceNamesCache.cs b/src/My.Extensions.Localization.Json/Caching/IResourceNamesCache.cs index ab23c6e..a8f0437 100644 --- a/src/My.Extensions.Localization.Json/Caching/IResourceNamesCache.cs +++ b/src/My.Extensions.Localization.Json/Caching/IResourceNamesCache.cs @@ -3,7 +3,18 @@ namespace My.Extensions.Localization.Json.Caching; +/// +/// Defines a cache for storing and retrieving collections of resource names by key. +/// public interface IResourceNamesCache { + /// + /// Gets the list of strings associated with the specified name, or adds a new list using the provided factory if + /// none exists. + /// + /// The key used to locate the associated list of strings. Cannot be null. + /// A function that generates a new list of strings if the specified name does not exist. Cannot be null. + /// The list of strings associated with the specified name. If the name was not present, returns the newly created + /// list from the factory. IList GetOrAdd(string name, Func> valueFactory); } diff --git a/src/My.Extensions.Localization.Json/Caching/ResourceNamesCache.cs b/src/My.Extensions.Localization.Json/Caching/ResourceNamesCache.cs index 0302db2..0a8d95f 100644 --- a/src/My.Extensions.Localization.Json/Caching/ResourceNamesCache.cs +++ b/src/My.Extensions.Localization.Json/Caching/ResourceNamesCache.cs @@ -4,10 +4,14 @@ namespace My.Extensions.Localization.Json.Caching; +/// +/// Provides a thread-safe cache for storing and retrieving lists of resource names by key. +/// public class ResourceNamesCache : IResourceNamesCache { private readonly ConcurrentDictionary> _cache = new(); + /// public IList GetOrAdd(string name, Func> valueFactory) => _cache.GetOrAdd(name, valueFactory); } diff --git a/src/My.Extensions.Localization.Json/Internal/IResourceStringProvider.cs b/src/My.Extensions.Localization.Json/Internal/IResourceStringProvider.cs index 3cafc6f..56ba47b 100644 --- a/src/My.Extensions.Localization.Json/Internal/IResourceStringProvider.cs +++ b/src/My.Extensions.Localization.Json/Internal/IResourceStringProvider.cs @@ -3,7 +3,18 @@ namespace My.Extensions.Localization.Json.Internal; +/// +/// Defines a provider for retrieving all resource strings for a specified culture. +/// public interface IResourceStringProvider { + /// + /// Retrieves all resource strings for the specified culture. + /// + /// The culture for which to retrieve resource strings. Cannot be null. + /// Specifies whether to throw an exception if resource strings for the specified culture are missing. If , an exception is thrown when resources are not found; otherwise, an empty list is returned. + /// A list of resource strings associated with the specified culture. The list is empty if no resources are found + /// and is . IList GetAllResourceStrings(CultureInfo culture, bool throwOnMissing); } diff --git a/src/My.Extensions.Localization.Json/Internal/JsonFileWatcher.cs b/src/My.Extensions.Localization.Json/Internal/JsonFileWatcher.cs index 8dc230a..7f8e379 100644 --- a/src/My.Extensions.Localization.Json/Internal/JsonFileWatcher.cs +++ b/src/My.Extensions.Localization.Json/Internal/JsonFileWatcher.cs @@ -3,6 +3,9 @@ namespace My.Extensions.Localization.Json.Internal; +/// +/// Provides a mechanism for monitoring changes to JSON files within a specified directory. +/// public class JsonFileWatcher : IDisposable { private const string JsonExtension = "*.json"; @@ -11,8 +14,16 @@ public class JsonFileWatcher : IDisposable private readonly FileSystemWatcher _filesWatcher; + /// + /// Occurs when a file or directory in the specified path is changed. + /// public event FileSystemEventHandler Changed; + /// + /// Initializes a new instance of the JsonFileWatcher class to monitor changes to JSON files in the specified + /// directory. + /// + /// The path to the directory to monitor for changes to JSON files. Must be a valid directory path. public JsonFileWatcher(string rootDirectory) { _filesWatcher = new(rootDirectory) @@ -24,17 +35,26 @@ public JsonFileWatcher(string rootDirectory) _filesWatcher.Changed += (s, e) => Changed?.Invoke(s, e); } + /// + /// Finalizes the JsonFileWatcher instance and releases unmanaged resources before the object is reclaimed by + /// garbage collection. + /// ~JsonFileWatcher() { Dispose(false); } + /// public void Dispose() { Dispose(true); GC.SuppressFinalize(true); } + /// + /// Releases the unmanaged resources used by the object and optionally releases the managed resources. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. public virtual void Dispose(bool disposing) { if (_disposed) diff --git a/src/My.Extensions.Localization.Json/Internal/JsonResourceLoader.cs b/src/My.Extensions.Localization.Json/Internal/JsonResourceLoader.cs index 862a97e..233715a 100644 --- a/src/My.Extensions.Localization.Json/Internal/JsonResourceLoader.cs +++ b/src/My.Extensions.Localization.Json/Internal/JsonResourceLoader.cs @@ -4,6 +4,10 @@ namespace My.Extensions.Localization.Json.Internal; +/// +/// Provides functionality to load string resources from a JSON file into a dictionary, using dot notation for nested +/// keys. +/// public static class JsonResourceLoader { private static readonly JsonDocumentOptions _jsonDocumentOptions = new() @@ -12,7 +16,12 @@ public static class JsonResourceLoader AllowTrailingCommas = true, }; - + /// + /// Loads key-value pairs from a JSON resource file at the specified path. + /// + /// The path to the JSON file containing resource definitions. Must refer to an existing file. + /// A dictionary containing resource keys and their corresponding values parsed from the file. Returns an empty + /// dictionary if the file does not exist or contains no resources. public static IDictionary Load(string filePath) { var resources = new Dictionary(); diff --git a/src/My.Extensions.Localization.Json/Internal/JsonResourceManager.cs b/src/My.Extensions.Localization.Json/Internal/JsonResourceManager.cs index b66f61e..957369f 100644 --- a/src/My.Extensions.Localization.Json/Internal/JsonResourceManager.cs +++ b/src/My.Extensions.Localization.Json/Internal/JsonResourceManager.cs @@ -7,17 +7,35 @@ namespace My.Extensions.Localization.Json.Internal; +/// +/// Provides access to localized string resources loaded from JSON files, supporting culture-specific lookups and +/// optional fallback to parent UI cultures. +/// public class JsonResourceManager { private readonly List _jsonFileWatchers = []; private readonly ConcurrentDictionary> _resourcesCache = new(); private readonly ConcurrentDictionary> _loadedFilesCache = new(); + /// + /// Initializes a new instance of the JsonResourceManager class using the specified resource directory and optional + /// resource name. + /// + /// The path to the directory containing the JSON resource files. Cannot be null or empty. + /// The name of the resource to load. If null, the default resource name is used. public JsonResourceManager(string resourcesPath, string resourceName = null) : this([resourcesPath], fallBackToParentUICultures: true, resourceName) { } + /// + /// Initializes a new instance of the JsonResourceManager class using the specified resource file paths and + /// configuration options. + /// + /// An array of file system paths to JSON resource files to be managed. If null, an empty array is used. + /// Indicates whether resource lookups should fall back to parent UI cultures when a resource is not found for the + /// requested culture. + /// The name of the resource to be managed. If null, the manager will use the default resource name resolution. public JsonResourceManager(string[] resourcesPaths, bool fallBackToParentUICultures, string resourceName = null) { ResourcesPaths = resourcesPaths ?? Array.Empty(); @@ -30,15 +48,31 @@ public JsonResourceManager(string[] resourcesPaths, bool fallBackToParentUICultu } } + /// + /// Initializes a new instance of the JsonResourceManager class using the specified resource file paths and an + /// optional resource name. + /// + /// An array of file system paths to JSON resource files to be managed. Each path should point to a valid resource + /// file. Cannot be null. + /// The name of the resource to be used for lookups. If null, the default resource name will be used. public JsonResourceManager(string[] resourcesPaths, string resourceName = null) : this(resourcesPaths, fallBackToParentUICultures: true, resourceName) { } + /// + /// Gets the name of the resource associated with this instance. + /// public string ResourceName { get; } + /// + /// Gets the collection of file system paths to resource files associated with the current instance. + /// public string[] ResourcesPaths { get; } + /// + /// Gets the file path to the resources file used by the application. + /// public string ResourcesFilePath { get; private set; } /// @@ -47,6 +81,15 @@ public JsonResourceManager(string[] resourcesPaths, string resourceName = null) /// public bool FallBackToParentUICultures { get; } + /// + /// Retrieves the set of localized resources for the specified culture, optionally including resources from parent + /// cultures. + /// + /// The culture for which to retrieve the resource set. This determines which localized resources are returned. + /// If , resources from parent cultures are included in the result; otherwise, only resources + /// for the specified culture are returned. + /// A containing the resources for the specified culture, or if no resources are available for that culture. public virtual ConcurrentDictionary GetResourceSet(CultureInfo culture, bool tryParents) { TryLoadResourceSet(culture); @@ -84,6 +127,11 @@ public virtual ConcurrentDictionary GetResourceSet(CultureInfo c } } + /// + /// Retrieves the localized string resource associated with the specified name for the current UI culture. + /// + /// The name of the resource to retrieve. This value is case-sensitive and must not be null. + /// The localized string value if found; otherwise, null. public virtual string GetString(string name) { var culture = CultureInfo.CurrentUICulture; @@ -116,6 +164,13 @@ public virtual string GetString(string name) return null; } + /// + /// Retrieves the localized string resource associated with the specified name and culture. + /// + /// The name of the resource to retrieve. This value is case-sensitive and must not be null. + /// The culture for which the resource should be retrieved. If the resource is not found for this culture and parent + /// culture fallback is enabled, parent cultures will be searched. + /// The localized string value for the specified resource name and culture, or null if the resource is not found. public virtual string GetString(string name, CultureInfo culture) { GetResourceSet(culture, tryParents: FallBackToParentUICultures); diff --git a/src/My.Extensions.Localization.Json/Internal/JsonStringProvider.cs b/src/My.Extensions.Localization.Json/Internal/JsonStringProvider.cs index 42e8f41..eee2371 100644 --- a/src/My.Extensions.Localization.Json/Internal/JsonStringProvider.cs +++ b/src/My.Extensions.Localization.Json/Internal/JsonStringProvider.cs @@ -5,6 +5,13 @@ namespace My.Extensions.Localization.Json.Internal; +/// +/// Provides resource string retrieval for JSON-based resource sets, supporting culture-specific access and caching of +/// resource names. +/// +/// A cache used to store and retrieve lists of resource names for specific cultures, improving performance by avoiding +/// repeated resource enumeration. +/// The resource manager responsible for accessing JSON resource sets and their associated strings for a given culture. public class JsonStringProvider(IResourceNamesCache resourceNamesCache, JsonResourceManager jsonResourceManager) : IResourceStringProvider { private string GetResourceCacheKey(CultureInfo culture) @@ -14,6 +21,7 @@ private string GetResourceCacheKey(CultureInfo culture) return $"Culture={culture.Name};resourceName={resourceName}"; } + /// public IList GetAllResourceStrings(CultureInfo culture, bool throwOnMissing) { var cacheKey = GetResourceCacheKey(culture); diff --git a/src/My.Extensions.Localization.Json/Internal/PathHelpers.cs b/src/My.Extensions.Localization.Json/Internal/PathHelpers.cs index da3c598..fe934e8 100644 --- a/src/My.Extensions.Localization.Json/Internal/PathHelpers.cs +++ b/src/My.Extensions.Localization.Json/Internal/PathHelpers.cs @@ -3,7 +3,15 @@ namespace My.Extensions.Localization.Json.Internal; +/// +/// Provides helper methods for working with file system paths related to the application's location. +/// public static class PathHelpers { + /// + /// Gets the root directory of the currently executing application. + /// + /// A string containing the full path to the application's root directory. Returns null if the directory cannot be + /// determined. public static string GetApplicationRoot() => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); } \ No newline at end of file diff --git a/src/My.Extensions.Localization.Json/JsonLocalizationOptions.cs b/src/My.Extensions.Localization.Json/JsonLocalizationOptions.cs index df578a3..0e9ff13 100644 --- a/src/My.Extensions.Localization.Json/JsonLocalizationOptions.cs +++ b/src/My.Extensions.Localization.Json/JsonLocalizationOptions.cs @@ -2,9 +2,18 @@ namespace My.Extensions.Localization.Json; +/// +/// Provides configuration options for JSON-based localization, including resource type and resource path settings. +/// public class JsonLocalizationOptions : LocalizationOptions { + /// + /// Gets or sets the strategy used to determine how resources are categorized or accessed. + /// public ResourcesType ResourcesType { get; set; } = ResourcesType.TypeBased; + /// + /// Gets or sets the collection of file system paths to resource directories used by the application. + /// public new string[] ResourcesPath { get; set; } = []; } \ No newline at end of file diff --git a/src/My.Extensions.Localization.Json/JsonLocalizationServiceCollectionExtensions.cs b/src/My.Extensions.Localization.Json/JsonLocalizationServiceCollectionExtensions.cs index 9bc278a..2242779 100644 --- a/src/My.Extensions.Localization.Json/JsonLocalizationServiceCollectionExtensions.cs +++ b/src/My.Extensions.Localization.Json/JsonLocalizationServiceCollectionExtensions.cs @@ -6,8 +6,17 @@ namespace Microsoft.Extensions.DependencyInjection; +/// +/// Provides extension methods for registering JSON-based localization services with an . +/// public static class JsonLocalizationServiceCollectionExtensions { + /// + /// Adds JSON-based localization services to the specified service collection. + /// + /// The service collection to which the JSON localization services will be added. Cannot be null. + /// The same service collection instance, with JSON localization services registered. public static IServiceCollection AddJsonLocalization(this IServiceCollection services) { ArgumentNullException.ThrowIfNull(services); @@ -19,6 +28,12 @@ public static IServiceCollection AddJsonLocalization(this IServiceCollection ser return services; } + /// + /// Adds JSON-based localization services to the specified service collection. + /// + /// The service collection to which the JSON localization services will be added. Cannot be null. + /// An action to configure the JSON localization options. Cannot be null. + /// The same instance of with JSON localization services registered. public static IServiceCollection AddJsonLocalization(this IServiceCollection services, Action setupAction) { ArgumentNullException.ThrowIfNull(services); diff --git a/src/My.Extensions.Localization.Json/JsonStringLocalizer.cs b/src/My.Extensions.Localization.Json/JsonStringLocalizer.cs index 2abc9e6..8e6176f 100644 --- a/src/My.Extensions.Localization.Json/JsonStringLocalizer.cs +++ b/src/My.Extensions.Localization.Json/JsonStringLocalizer.cs @@ -12,6 +12,10 @@ namespace My.Extensions.Localization.Json; using My.Extensions.Localization.Json.Caching; +/// +/// Provides string localization services using JSON-based resource files. Supports retrieving localized strings and +/// formatting them for the current or specified culture. +/// public class JsonStringLocalizer : IStringLocalizer { private readonly ConcurrentDictionary _missingManifestCache = new(); @@ -21,6 +25,13 @@ public class JsonStringLocalizer : IStringLocalizer private string _searchedLocation = string.Empty; + /// + /// Initializes a new instance of the JsonStringLocalizer class using the specified resource manager, resource names + /// cache, and logger. + /// + /// The resource manager that provides access to JSON-based localization resources. + /// The cache used to store and retrieve resource names for efficient localization lookups. + /// The logger used to record localization-related events and errors. public JsonStringLocalizer( JsonResourceManager jsonResourceManager, IResourceNamesCache resourceNamesCache, @@ -31,6 +42,15 @@ public JsonStringLocalizer( { } + /// + /// Initializes a new instance of the JsonStringLocalizer class using the specified resource manager, string + /// provider, and logger. + /// + /// The resource manager that provides access to JSON-based localization resources. + /// The provider used to retrieve localized strings from resources. + /// The logger used to record localization-related events and errors. + /// Thrown if , , or is null. public JsonStringLocalizer( JsonResourceManager jsonResourceManager, IResourceStringProvider resourceStringProvider, @@ -53,6 +73,7 @@ public JsonStringLocalizer( _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } + /// public LocalizedString this[string name] { get @@ -65,6 +86,7 @@ public LocalizedString this[string name] } } + /// public LocalizedString this[string name, params object[] arguments] { get @@ -78,9 +100,18 @@ public LocalizedString this[string name] } } + /// public virtual IEnumerable GetAllStrings(bool includeParentCultures) => GetAllStrings(includeParentCultures, CultureInfo.CurrentUICulture); + /// + /// Returns all localized strings available for the specified culture, optionally including strings from parent + /// cultures. + /// + /// true to include localized strings from parent cultures in addition to the specified culture; otherwise, false. + /// The culture for which to retrieve localized strings. Cannot be null. + /// An enumerable collection of LocalizedString objects representing all available localized strings for the + /// specified culture. protected virtual IEnumerable GetAllStrings(bool includeParentCultures, CultureInfo culture) { ArgumentNullException.ThrowIfNull(culture); @@ -96,6 +127,14 @@ protected virtual IEnumerable GetAllStrings(bool includeParentC } } + /// + /// Retrieves the localized string resource for the specified name and culture, returning null if the resource is + /// missing or unavailable. + /// + /// The name of the string resource to retrieve. Cannot be null. + /// The culture for which to retrieve the resource. If null, the current UI culture is used. + /// The localized string resource associated with the specified name and culture, or null if the resource is not + /// found. protected string GetStringSafely(string name, CultureInfo culture) { ArgumentNullException.ThrowIfNull(name); diff --git a/src/My.Extensions.Localization.Json/JsonStringLocalizerFactory.cs b/src/My.Extensions.Localization.Json/JsonStringLocalizerFactory.cs index a63e550..2ac36ba 100644 --- a/src/My.Extensions.Localization.Json/JsonStringLocalizerFactory.cs +++ b/src/My.Extensions.Localization.Json/JsonStringLocalizerFactory.cs @@ -14,6 +14,10 @@ namespace My.Extensions.Localization.Json; using My.Extensions.Localization.Json.Caching; +/// +/// Provides an implementation of that loads localized strings from JSON resource +/// files. Enables localization support for applications using JSON-based resources. +/// public class JsonStringLocalizerFactory : IStringLocalizerFactory { private readonly IResourceNamesCache _resourceNamesCache = new ResourceNamesCache(); @@ -23,6 +27,12 @@ public class JsonStringLocalizerFactory : IStringLocalizerFactory private readonly bool _fallBackToParentUICultures = true; private readonly ILoggerFactory _loggerFactory; + /// + /// Initializes a new instance of the JsonStringLocalizerFactory class using the specified localization options and + /// logger factory. + /// + /// The options used to configure JSON-based localization behavior. + /// The factory used to create logger instances for logging localization events and errors. public JsonStringLocalizerFactory( IOptions localizationOptions, ILoggerFactory loggerFactory) @@ -30,6 +40,16 @@ public JsonStringLocalizerFactory( { } + /// + /// Initializes a new instance of the JsonStringLocalizerFactory class using the specified localization and logging + /// options. + /// + /// The localization options that configure resource paths and resource type for JSON-based localization. Cannot be + /// null. + /// The logger factory used to create loggers for localization operations. Cannot be null. + /// The request localization options that determine culture fallback behavior. May be null; if null, fallback to + /// parent UI cultures is enabled by default. + /// Thrown if or is null. public JsonStringLocalizerFactory( IOptions localizationOptions, ILoggerFactory loggerFactory, @@ -43,6 +63,7 @@ public JsonStringLocalizerFactory( _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); } + /// public IStringLocalizer Create(Type resourceSource) { ArgumentNullException.ThrowIfNull(resourceSource); @@ -68,6 +89,7 @@ public IStringLocalizer Create(Type resourceSource) return _localizerCache.GetOrAdd($"culture={CultureInfo.CurrentUICulture.Name}, typeName={typeName}", _ => CreateJsonStringLocalizer(paths, typeName)); } + /// public IStringLocalizer Create(string baseName, string location) { ArgumentNullException.ThrowIfNull(baseName); @@ -97,6 +119,14 @@ public IStringLocalizer Create(string baseName, string location) }); } + /// + /// Creates a new instance of the using the specified resource paths and resource + /// name. + /// + /// An array of file system paths that specify the locations of JSON resource files to be used for localization. + /// The name of the resource to be localized. If is null, localization will be based + /// on the provided resource paths only. + /// A configured to provide localized strings from the specified resources. protected virtual JsonStringLocalizer CreateJsonStringLocalizer( string[] resourcesPaths, string resourceName) diff --git a/src/My.Extensions.Localization.Json/ResourcesType.cs b/src/My.Extensions.Localization.Json/ResourcesType.cs index d320d16..1dbe792 100644 --- a/src/My.Extensions.Localization.Json/ResourcesType.cs +++ b/src/My.Extensions.Localization.Json/ResourcesType.cs @@ -1,7 +1,17 @@ namespace My.Extensions.Localization.Json; +/// +/// Specifies the strategy used to locate and manage application resources, such as strings or images, for localization +/// or configuration purposes. +/// public enum ResourcesType { + /// + /// Specifies that the operation or value is determined based on cultural or locale-specific rules. + /// CultureBased, + /// + /// Represents an object or operation that is determined or influenced by its type information. + /// TypeBased } \ No newline at end of file diff --git a/src/My.Extensions.Localization.Json/StringLocalizerExtensions.cs b/src/My.Extensions.Localization.Json/StringLocalizerExtensions.cs index 8d0516a..62eb859 100644 --- a/src/My.Extensions.Localization.Json/StringLocalizerExtensions.cs +++ b/src/My.Extensions.Localization.Json/StringLocalizerExtensions.cs @@ -4,9 +4,20 @@ namespace My.Extensions.Localization.Json; +/// +/// Provides extension methods for retrieving localized strings using strongly-typed resource property expressions. +/// public static class StringLocalizerExtensions { - public static LocalizedString GetString( - this IStringLocalizer stringLocalizer, - Expression> propertyExpression) => stringLocalizer[(propertyExpression.Body as MemberExpression).Member.Name]; + /// + /// Retrieves a localized string for the specified property of a resource type using a strongly-typed expression. + /// + /// The resource type containing the property for which to retrieve the localized string. + /// The string localizer instance used to obtain localized values for the resource type. + /// An expression that identifies the string property of the resource type to localize. Must refer to a property of + /// type . + /// A containing the localized value for the specified property. If no localized value + /// is found, the property name is returned as the value. + public static LocalizedString GetString(this IStringLocalizer stringLocalizer, Expression> propertyExpression) + => stringLocalizer[(propertyExpression.Body as MemberExpression).Member.Name]; } \ No newline at end of file