CommunityToolkit / dotnet

.NET Community Toolkit is a collection of helpers and APIs that work for all .NET developers and are agnostic of any specific UI platform. The toolkit is maintained and published by Microsoft, and part of the .NET Foundation.
https://docs.microsoft.com/dotnet/communitytoolkit/?WT.mc_id=dotnet-0000-bramin
Other
3.04k stars 298 forks source link

[Proposal] LocalizationResourceManager #312

Open brminnick opened 3 years ago

brminnick commented 3 years ago

LocalizationResourceManager

Summary

The LocalizationResourceManager class is a helper class that enables users to respond to culture changes at runtime.

Detailed Design

LocalizationResourceManager.shared.cs

public class LocalizationResourceManager : INotifyPropertyChanged
{
  public static LocalizationResourceManager Current;

  private LocalizationResourceManager();

  public void Init(ResourceManager resource);
  public void Init(ResourceManager resource, CultureInfo initialCulture);
  public object GetValue(string resourceKey);

  public object this[string resourceKey] => GetValue(resourceKey);

  public CultureInfo CurrentCulture { get; set; }
}

Usage Syntax

XAML Usage

N/A

C# Usage

LocalizationResourceManager.Current.PropertyChanged += (_, _) => AppResources.Culture = LocalizationResourceManager.Current.CurrentCulture;
LocalizationResourceManager.Current.Init(AppResources.ResourceManager);

LocalizationResourceManager.Current.CurrentCulture = newCulture;
brminnick commented 3 years ago

Closing for the following reasons:

brminnick commented 2 years ago

Reopening based on our discussion during the June Standup: https://www.youtube.com/watch?v=t3g_NrQfE8g

VladislavAntonyuk commented 2 years ago

Why I suggest to keep it in MCT?

  1. It works great with TranslateExtension, which depends on MAUI. So if we decide to add TranslateExtension we will need to depend on Community Toolkit dotnet.
  2. Based on the first point. Splitting Localization classes on different packages maybe not a great customer experience
  3. Minor but it will be easier for XCT users migrate to MCT
  4. As for me localization resources are mostly related to UI (like button text or user error messages - not logs), so keep it somewhere in Core library may not give a lot of benefit. User may store Resx files wherever he wants. LocalizationResourceManager only needs ResourceManager reference.
bijington commented 2 years ago

I agree that we should probably offer all or nothing rather than take on a dependency. I am trying to think on whether there could be a compromise but nothing is coming to mind

VladislavAntonyuk commented 2 years ago

It can work as a standalone feature but as I described in the article LocalizationResourceManager and TranslateExtension work better together: https://vladislavantonyuk.azurewebsites.net/articles/Localize-.NET-MAUI-application

pictos commented 2 years ago

For me, we should implement this in a more Core lib. in other to add value across other .NET UI frameworks (and maybe in non UI frameworks as well). I'll express that by commenting on the points that @VladislavAntonyuk mentioned.

So from 1 and 2

  1. It works great with TranslateExtension, which depends on MAUI. So if we decide to add TranslateExtension we will need to depend on Community Toolkit dotnet.
  2. Based on the first point. Splitting Localization classes on different packages maybe not a great customer experience

Now that CommunityToolkits are all in the same org, we should start thinking about ways to add features to all of them. Like the CommunityToolkit.Maui.Core will be used by other Toolkits that you will target other MAUI flavors, we can have a dependency on the CommunityToolkit.Common if that makes sense. We can ship the CommunityToolkit.Common with our NuGet, so devs don't need to install it by themself.

  1. Minor but it will be easier for XCT users migrate to MCT

Can't see why will be hard to migrate from XCT to MCT if this feature is on CommunityToolkit.Common. Repeating my self, we can ship that package with our NuGet.

  1. As for me localization resources are mostly related to UI (like button text or user error messages - not logs), so keep it somewhere in Core library may not give a lot of benefit. User may store Resx files wherever he wants. LocalizationResourceManager only needs ResourceManager reference.

You can use resx files in ConsoleApps (maybe you're developing a dotnet tool and want to support multiple languages), and also can be used in other .NET areas, that include UI, like ASP.NET, WPF, UWP, etc. I mean, MAUI isn't the only UI framework for .NET so having this feature in a Core library will help other toolkits, applications and libs to create and manage their localization resources like we want to do here

brminnick commented 2 years ago

Because this Proposal is not specific to .NET MAUI, my vote is to implement this feature in the CommunityToolkit/dotnet repo so that additional devs can benefit from it.

Hey @sergio0694! Do agree that this feature is best scoped for CommunityToolkit.Common?

Sergio0694 commented 2 years ago

Leaving an update here as @brminnick asked - right now the 8.0 release is feature complete and I'm just working on stabilizing stuff and fixing last minute bugs. I'm happy to look into this once that is out though, for sure 🙂

powerdude commented 2 years ago

if this library takes this forward, I hope we can not have the public static LocalizationResourceManager Current; property. With the new structure of Maui and dependency injection, there should be less of a need to add static properties like this.

maxkoshevoi commented 2 years ago

Any updates on this? This has been marked as in-progress champion for three months now, I think

Sergio0694 commented 2 years ago

Those labels were just leftovers from when the issue was moved to this repo, but they have no meaning here. I've removed them 🙂

VladislavAntonyuk commented 2 years ago

Hi @Sergio0694 , any updates about this issue?

jrahma commented 1 year ago

Would love to see this soon.

AlleSchonWeg commented 1 year ago

Hi, i tried to migrate from XF to MAUI and i have 111 references to the LocalizedString class im my project. Also 71 references to the Translate extensions in xaml. What is now the prefered way to migrate my code to MAUI? It is not better to keep this functionality in the MAUI Toolkit and remove it later once a better place is found?!

Thanks

SirJohnK commented 1 year ago

Until a final solution is made for this, have I created a replacement library for .NET MAUI. :smiley: https://github.com/SirJohnK/LocalizationResourceManager.Maui

hansmbakker commented 2 months ago

Leaving an update here as @brminnick asked - right now the 8.0 release is feature complete and I'm just working on stabilizing stuff and fixing last minute bugs. I'm happy to look into this once that is out though, for sure 🙂

@Sergio0694 is there any news on this? I'd love to have better localization support in MAUI, with MAUI-agnostic interfaces so that they can be used from viewmodel projects as well!

bijington commented 2 months ago

It's not MAUI agnostic but over recently made use of this library which has been great: https://github.com/SirJohnK/LocalizationResourceManager.Maui

hansmbakker commented 2 months ago

It's not MAUI agnostic but over recently made use of this library which has been great: https://github.com/SirJohnK/LocalizationResourceManager.Maui

I know, and the library you mentioned seems meant as a temporary solution by its author until this proposal is solved:

So until we have a official solution, or anyway is added to MCT, I have created this library for .NET

For this reason, I'd still like to hear from @Sergio0694 or @brminnick what the plans are regarding this proposal.

Other than that, I do like @SirJohnK's library for now as it does solve some issues, and I suggested to extract e.g. the interfaces so that it could be used from Maui-agnostic VM projects via Dependency Injection.

bijington commented 2 months ago

@hansmbakker I see your point. If it is a MAUI agnostic library then this repository/toolkit is not the right place for it. It would be the .NET Community Toolkit. I don't know what their plans are, maybe we will hear from them.

I guess one big challenge of making it agnostic is losing the value that comes from classes like TranslateExtension and TranslateBindingExtension

SirJohnK commented 2 months ago

As suggested by @hansmbakker, with the latest prerelease (1.3.0-alpha.4) of the LocalizationResourceManager.Maui, have I created the LocalizationResourceManager.Maui.Core package (1.0.0-alpha.1) that CAN be used from Maui-agnostic VM projects via Dependency Injection!😅

Read more here!

bijington commented 2 months ago

Oh nice! If someone wanted to use this in the MAUI world would you expect that they use the Core and Maui packages? Of course the Maui one could depend on Core so a developer only needs to bring in one package. But this then leads me onto my point about where things belong in specific toolkits

SirJohnK commented 2 months ago

This was always intended to be used in the MAUI world, but now you have the option to have a non MAUI project for your ViewModels with the Core library and the MAUI library, with dependence on Core, in your MAUI app project.

Technically, Core could be used without MAUI, but then you need to implement the ILocalizationResourceManager interface yourself.

@hansmbakker, out of curiosity, how would you use the Core library and why?

AndrewKeepCoding commented 2 months ago

For those in WinUI, try the WinUI3Localizer. I created it for runtime localization.🙂

hansmbakker commented 2 months ago

@hansmbakker, out of curiosity, how would you use this and why?

Testability and separation of concerns are some reasons.

I'm following The MVVM Pattern in .NET MAUI by @PieEatingNinjas.

The idea is to ensure a clear separation of the ViewModels from the View layer by having them in a different project. This way the ViewModels have no way of referencing MAUI-specific code - but via DI and interfaces they can still call functions in MAUI. The ViewModels project can be unit tested without UI code.