-
-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How can I use multiple ResourceManagers? #19
Comments
Hi, @santo998!
<ContentPage Title="{loc:Translate MainPageTitle}">
/Regards Johan |
Hi @SirJohnK
Well, it can be acomplished modifying LocalizationResourceManager class. And, on its GetValue(...) method, instead of doing this: It could search ResourceManager by key and then search the value. Adding a key parameter or a method overload.
I even feel it better having one .resx per view, as I use ResX Manager extension and it allows me to filter per file. I don't see the issue of having 200 small files instead of one big one. It's total size will be a little higher, and compilation could take few milliseconds more, but JIT would benefict me loading only one view .resx at a time. If I use only one big .resx, then I would have lot of "trash" on my keys. So, I really prefer having multiple files. I have three options then:
I don't want the 3rd, because it defeats the purpose of using the library. My ideal use cases would be: For the XAML (IF POSSIBLE (adding some xmlns maybe)): If not possible: When registering: From ViewModel:
Even better if I could define ResourceManager file name once, setting some new ILocalizationResourceManager property, like this:
Maybe it can be implemented on another ways I'm not considering here. /Regards Santiago |
It could search by key on the desired ResourceManager file, and have a fallback option to search on others ResourceManagers if value isn't found. It could get even better, because you could register the ResourceManager objects as Lazy<> so they will be load as needed. If fallback option isn't specified, then it wouldn't search on others ResourceManagers and they won't be loaded until they are specified. |
I need to think about this and come back to you, since I am of on vacation at the moment. /Johan |
@SirJohnK thank you so much! I just played around with the code to test if it's possible, and the only problem is on TranslateExtension: |
@santo998 , finally I have had the time to look into this! 😅
Register with Name/key:
Reference specific ResourceManager in XAML:
Reference specific ResourceManager in Code:
The only issue/challenge with this solution is that you do not have the option to set The reason for this is:
But maybe this is not a big issue and this solution is good enough!? I would love if you have the time to look at this draft and hear what you think! /Regards Johan |
@santo998 , did you / will you have the time to review this? (Would really appreciate your input!) |
@SirJohnK sorry, I was busy, but this was in my to do list. How can I test it? Like, is there a preview Nuget? Or I have to clone the repo? I would like to test it on my test app first, and later review the code. |
@santo998 , no problem! Just happy that you are willing to review this.
/Johan |
@SirJohnK, I updated your library in my test project and used it a bit. Pretty awesome! However, there are some "pain points":
In ViewModel, it can be avoided by creating a wrapper method where you hardcode the ResourceManager key, and then reference that method in all your ViewModel code. I wonder if something like that could be done in XAML...
I wonder if those issues could be solved by creating another LocalizationResourceManager class that handles the multiple .resx localization. I would split the LocalizationResourceManager class into three:
|
@santo998 , thanks! 😄 Yes, I anticipated the "pain points". 😃
I think I have found a pretty elegant solution to that.
I think I have found a pretty elegant solution for this too!
This is tricky! Not sure it is easily solved. But to be fair, we do not have IntelliSense for any of the resource texts and with the new features, mentioned above, I do not think it will be a big issue. I will soon release a /Regards Johan |
@SirJohnK amazing! It took me some readings to fully understand the solutions you encountered. Pretty creative making the Page implement an ISpecificResourceManager interface. Now the "pain points" are gone! I would love to test your new version. I will wait. Now I think your library can be massively adopted by the MAUI community! Thank you in advance, |
Hi @SirJohnK , I came across your nuget package and saw at first that it didn't support separation of resource files and would only get the first resource out of all files so I tried to make my own version of it (that sadly only works in Debug mode and not in Release). Then I saw this open issue and saw you created a new prerelease version a couple days ago and it seems to work nicely from very briefly trying it. How stable is that version in terms of crashing/memory leaks? Do you expect to keep the support for multiple resource files in the official version later on too? Like @santo998 , if there are any tests that I could do then I would love to do them since it looks quite promising. |
Hi, @Wout-M ! Yes, the Theses resources can be referenced in a number of ways:
I think the Help testing is always welcome! Try testing it for your needs and please report back what those are and how it works. /Regards Johan |
Hey @SirJohnK, I did some more testing and might have found a small issue when building the app in I have multiple pages for an introduction in my app that look almost the same, but get their text from different resource files since they all have some slight different functionality, so the resource files for these pages all have a The resources are registered as follows: builder
.UseMauiApp<App>()
// Do other stuff
.UseLocalizationResourceManager(settings =>
{
settings.AddResource(WelcomeResources.ResourceManager, nameof(WelcomeResources));
settings.AddResource(PickLanguageResources.ResourceManager, nameof(PickLanguageResources));
settings.SuppressTextNotFoundException(true, "'{0}' not found!");
settings.RestoreLatestCulture(true);
}); The pages have the specific resource key with the attribute/interface (I wanted to try both to be sure it wasn't related to the implementation of one of th methods): [SpecificResourceManager(nameof(WelcomeResources))]
public partial class WelcomePage : ContentPage
{
public WelcomePage(WelcomeViewModel vm)
{
InitializeComponent();
BindingContext = vm;
}
} //[SpecificResourceManager(nameof(PickLanguageResources))]
public partial class PickLanguagePage : ContentPage, ISpecificResourceManager
{
public PickLanguagePage(PickLanguageViewModel vm)
{
InitializeComponent();
BindingContext = vm;
}
public string ResourceManager => nameof(PickLanguageResources);
} In the page it's used like this: <?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:localization="clr-namespace:LocalizationResourceManager.Maui;assembly=LocalizationResourceManager.Maui"
xmlns:view="clr-namespace:Build.Apps.Document.View.Views"
xmlns:vm="clr-namespace:Build.Apps.Document.ViewModel.ViewModels.PickLanguage;assembly=Build.Apps.Document.ViewModel"
x:Class="Build.Apps.Document.View.Pages.PickLanguagePage"
x:DataType="vm:PickLanguageViewModel"
Shell.NavBarIsVisible="False">
<Grid RowDefinitions="3*,*,*"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Margin="0,0,0,30">
<Image Source="Images/logo.png"
HeightRequest="128"
WidthRequest="128"
HorizontalOptions="Center"
VerticalOptions="Center"/>
<VerticalStackLayout Grid.Row="1"
Spacing="5"
Padding="30,30,30,0">
<Label Text="{localization:Translate Title}"
FontSize="Title"
FontAttributes="Bold"/>
<Label Text="{localization:Translate SubText, ResourceManager=PickLanguageResources}"/>
</VerticalStackLayout>
<VerticalStackLayout Grid.Row="2"
Spacing="30"
Padding="30"
VerticalOptions="End">
<Picker ItemsSource="{Binding Languages}"
SelectedItem="{Binding SelectedLanguage}"
ItemDisplayBinding="{Binding NativeName}"
Title="{localization:Translate PickLanguage}"/>
<Button Text="{localization:Translate Next, ResourceManager=GeneralResources}"
Command="{Binding PickLanguageCommand}"
HeightRequest="50"
CornerRadius="100"/>
</VerticalStackLayout>
</Grid>
</ContentPage> When building in Debug mode, the So in the case above it would pick I tried building it with or without the R8 linker to see if that meddled with something, but that doesn't seem to make a difference. |
@Wout-M , nice find! 👍 Will look into this asap. 😄 |
@Wout-M , I found the reason why it is not working in |
@SirJohnK Oh no that sounds rough, but it would definitely also explain why my solution kept crashing when I used At the moment as a workaround I just specify the ResourceManager specifically for the translations where the keys would be in multiple resource files which seems to work fine apart from it being a little extra work. |
@Wout-M , I think I found a solution! 😄
|
@SirJohnK I'll go try it out! I'll get back to you as soon as I can with what I find |
@SirJohnK From some very quick tests it seems to work, nice find with the solution! |
Great!👍 Will try to release it soon!😅 (Wanted to do some tests first) |
These are some of the designs we considered for our project
Here's an example of the 2nd case:
|
I like to have a .resx file per ContentPage, so my MauiApp builder looks like:
Problem is that all my views .resx files have a key named "Title".
So, I use ILocalizationResourceManager from my ViewModel and the translate extension from my views XAML, but I always get Title from LocalizacionPage's resource manager (the first one I registered on my MauiApp builder).
I mean, if I write this on MainPage's XAML:
<ContentPage Title="{loc:Translate Title}">
Title gets LocalizacionPage's resource manager "Title" key value, but I want MainPage's resource manager value.
Or if I go:
titleTest var gets LocalizacionPage's resource manager "Title" key value, but I want MainPage's resource manager value.
So, how could I tell ILocalizationResourceManager to use certain ResourceManager?
Or even better:
The text was updated successfully, but these errors were encountered: