diff --git a/Directory.Packages.props b/Directory.Packages.props index 39c7d4a..ab61cd4 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -29,7 +29,7 @@ - + diff --git a/samples/Directory.Packages.props b/samples/Directory.Packages.props index f2a89f5..12bd543 100644 --- a/samples/Directory.Packages.props +++ b/samples/Directory.Packages.props @@ -19,7 +19,7 @@ - + diff --git a/src/AndreGoepel.Marten.Identity.Blazor/Components/IdentityLocalizedComponentBase.cs b/src/AndreGoepel.Marten.Identity.Blazor/Components/IdentityLocalizedComponentBase.cs index 70bc1e2..712c4a7 100644 --- a/src/AndreGoepel.Marten.Identity.Blazor/Components/IdentityLocalizedComponentBase.cs +++ b/src/AndreGoepel.Marten.Identity.Blazor/Components/IdentityLocalizedComponentBase.cs @@ -1,44 +1,20 @@ +using AndreGoepel.Design.Blazor.Components; using AndreGoepel.Marten.Identity.Blazor.Resources; -using Microsoft.AspNetCore.Components; namespace AndreGoepel.Marten.Identity.Blazor.Components; /// -/// Base for identity UI components that render their own text via -/// instead of a page-local copy of the same helper (#114). +/// Base for identity UI components that render their own text via T(string) instead of a +/// page-local copy of the same helper (#114). Thin subclass of the design system's generic +/// closed over , so +/// pages can @inherits IdentityLocalizedComponentBase without spelling out the closed +/// generic name. /// /// -/// A component must not @inject IStringLocalizer<IdentityStrings> directly: that -/// is a required injection, so rendering it throws on any host — or bUnit test — that never -/// called AddMartenIdentityBlazor. Resolving through -/// instead avoids that, which is why every translated page needs the same pair of methods; -/// this base class is the one place that pair is defined. Inherit it with @inherits -/// IdentityLocalizedComponentBase rather than repeating @inject IServiceProvider -/// Services + the two T overloads in each page. -/// -/// Not to be confused with — or replaced by — LocalizedComponentBase from -/// AndreGoepel.Design.Blazor: that one resolves against the design system's own -/// DesignStrings resx and returns the key unchanged for anything it does not know, -/// so inheriting it here renders every identity page as raw resource keys. The name differs -/// deliberately: _Imports.razor pulls in both namespaces, so a shared name would be -/// ambiguous (CS0104). -/// -/// -/// Public rather than internal: the Razor compiler generates a routable (@page) -/// component's partial class as public, and a public class cannot derive from an internal -/// base (CS0060). Not intended for use outside this assembly regardless. -/// +/// Not to be confused with — or replaced by — AndreGoepel.Design.Blazor's own non-generic +/// LocalizedComponentBase: that one is closed over the design system's own +/// DesignStrings resx, not . The name differs from the +/// generic base deliberately: _Imports.razor pulls in both namespaces, so a shared name +/// would be ambiguous (CS0104). /// -public abstract class IdentityLocalizedComponentBase : ComponentBase -{ - [Inject] - private IServiceProvider Services { get; set; } = default!; - - /// Looks up for the current UI culture. - protected string T(string key) => Services.IdentityText(key); - - /// - /// Formats the resolved string with . - protected string T(string key, params object[] arguments) => - Services.IdentityText(key, arguments); -} +public abstract class IdentityLocalizedComponentBase : LocalizedComponentBase; diff --git a/src/AndreGoepel.Marten.Identity.Blazor/Resources/IdentityTextExtensions.cs b/src/AndreGoepel.Marten.Identity.Blazor/Resources/IdentityTextExtensions.cs deleted file mode 100644 index 0ef15b4..0000000 --- a/src/AndreGoepel.Marten.Identity.Blazor/Resources/IdentityTextExtensions.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Globalization; -using System.Resources; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Localization; - -namespace AndreGoepel.Marten.Identity.Blazor.Resources; - -/// -/// Resolves the identity UI's strings, tolerating a host that has not registered localization. -/// -/// -/// Pages must not @inject IStringLocalizer<IdentityStrings> directly: that is a -/// required injection, so rendering a page throws on any host — or bUnit test — that never -/// called AddMartenIdentityBlazor. This library ships routable pages that consuming -/// apps render in their own tests, so the failure would land in code the consumer never -/// touched. Same reasoning, and same shape, as DesignTextExtensions in -/// AndreGoepel.Design.Blazor 1.2.1. -/// -internal static class IdentityTextExtensions -{ - // Same base name the IStringLocalizer path uses, so both routes read one resx pair and - // no English text is duplicated in code. - private static readonly ResourceManager Fallback = new( - typeof(IdentityStrings).FullName!, - typeof(IdentityStrings).Assembly - ); - - /// - /// Looks up for the current UI culture. Prefers a registered - /// so a host can substitute one; otherwise reads the - /// embedded resources directly. - /// - internal static string IdentityText(this IServiceProvider services, string key) - { - if (services.GetService>() is { } localizer) - { - var localized = localizer[key]; - if (!localized.ResourceNotFound) - { - return localized.Value; - } - } - - // CurrentUICulture is what request localization sets per request, so the fallback - // stays culture-aware without any DI involvement. - return Fallback.GetString(key, CultureInfo.CurrentUICulture) ?? key; - } - - /// - internal static string IdentityText( - this IServiceProvider services, - string key, - params object[] arguments - ) => string.Format(CultureInfo.CurrentCulture, services.IdentityText(key), arguments); -} diff --git a/src/AndreGoepel.Marten.Identity.Blazor/packages.lock.json b/src/AndreGoepel.Marten.Identity.Blazor/packages.lock.json index 45c10a7..4da9704 100644 --- a/src/AndreGoepel.Marten.Identity.Blazor/packages.lock.json +++ b/src/AndreGoepel.Marten.Identity.Blazor/packages.lock.json @@ -4,9 +4,9 @@ "net10.0": { "AndreGoepel.Design.Blazor": { "type": "Direct", - "requested": "[1.4.2, )", - "resolved": "1.4.2", - "contentHash": "57laKLfocolPOcRbBLP0GccM9k3T+grGAnlv/BpUmH9n1SnbxAqq6YEotTq5E9xThMq9WvuSGv/VUTB1B6Bdww==", + "requested": "[1.6.0, )", + "resolved": "1.6.0", + "contentHash": "ciJLnfD2c8mXk/WMPlybrwEhWnpsA8IGTrNAzo+5mRLAy0k7MQFWNPrTOlW536BYAhb0Ri3INseVBQfV8fX8ww==", "dependencies": { "Radzen.Blazor": "11.1.7" } diff --git a/tests/AndreGoepel.Marten.Identity.Blazor.Tests/packages.lock.json b/tests/AndreGoepel.Marten.Identity.Blazor.Tests/packages.lock.json index 251bddb..a4b819f 100644 --- a/tests/AndreGoepel.Marten.Identity.Blazor.Tests/packages.lock.json +++ b/tests/AndreGoepel.Marten.Identity.Blazor.Tests/packages.lock.json @@ -384,7 +384,7 @@ "andregoepel.marten.identity.blazor": { "type": "Project", "dependencies": { - "AndreGoepel.Design.Blazor": "[1.4.2, )", + "AndreGoepel.Design.Blazor": "[1.6.0, )", "AndreGoepel.Marten.Configuration": "[1.0.1, )", "AndreGoepel.Marten.Identity": "[1.8.0, )", "Marten": "[9.19.0, )", @@ -399,9 +399,9 @@ }, "AndreGoepel.Design.Blazor": { "type": "CentralTransitive", - "requested": "[1.4.2, )", - "resolved": "1.4.2", - "contentHash": "57laKLfocolPOcRbBLP0GccM9k3T+grGAnlv/BpUmH9n1SnbxAqq6YEotTq5E9xThMq9WvuSGv/VUTB1B6Bdww==", + "requested": "[1.6.0, )", + "resolved": "1.6.0", + "contentHash": "ciJLnfD2c8mXk/WMPlybrwEhWnpsA8IGTrNAzo+5mRLAy0k7MQFWNPrTOlW536BYAhb0Ri3INseVBQfV8fX8ww==", "dependencies": { "Radzen.Blazor": "11.1.7" } diff --git a/tests/AndreGoepel.Marten.Identity.IntegrationTests/packages.lock.json b/tests/AndreGoepel.Marten.Identity.IntegrationTests/packages.lock.json index a58f01a..b037730 100644 --- a/tests/AndreGoepel.Marten.Identity.IntegrationTests/packages.lock.json +++ b/tests/AndreGoepel.Marten.Identity.IntegrationTests/packages.lock.json @@ -431,7 +431,7 @@ "andregoepel.marten.identity.blazor": { "type": "Project", "dependencies": { - "AndreGoepel.Design.Blazor": "[1.4.2, )", + "AndreGoepel.Design.Blazor": "[1.6.0, )", "AndreGoepel.Marten.Configuration": "[1.0.1, )", "AndreGoepel.Marten.Identity": "[1.8.0, )", "Marten": "[9.19.0, )", @@ -446,9 +446,9 @@ }, "AndreGoepel.Design.Blazor": { "type": "CentralTransitive", - "requested": "[1.4.2, )", - "resolved": "1.4.2", - "contentHash": "57laKLfocolPOcRbBLP0GccM9k3T+grGAnlv/BpUmH9n1SnbxAqq6YEotTq5E9xThMq9WvuSGv/VUTB1B6Bdww==", + "requested": "[1.6.0, )", + "resolved": "1.6.0", + "contentHash": "ciJLnfD2c8mXk/WMPlybrwEhWnpsA8IGTrNAzo+5mRLAy0k7MQFWNPrTOlW536BYAhb0Ri3INseVBQfV8fX8ww==", "dependencies": { "Radzen.Blazor": "11.1.7" }