From 1fb8b0a8349923747fdc20fc1ce6aa2430e8497d Mon Sep 17 00:00:00 2001 From: ema Date: Fri, 1 Dec 2023 03:07:09 +0800 Subject: [PATCH] Fix resx in other dll cant be read by SourceGenerators (#4) --- .../Antelcat.I18N.Shared.projitems | 1 + .../I18NAssemblyProvider.cs | 24 +++++++ src/Antelcat.I18N.Shared/I18NExtension.cs | 68 ++++++++++--------- 3 files changed, 60 insertions(+), 33 deletions(-) create mode 100644 src/Antelcat.I18N.Shared/I18NAssemblyProvider.cs diff --git a/src/Antelcat.I18N.Shared/Antelcat.I18N.Shared.projitems b/src/Antelcat.I18N.Shared/Antelcat.I18N.Shared.projitems index 748a86c..5791f86 100644 --- a/src/Antelcat.I18N.Shared/Antelcat.I18N.Shared.projitems +++ b/src/Antelcat.I18N.Shared/Antelcat.I18N.Shared.projitems @@ -11,6 +11,7 @@ + diff --git a/src/Antelcat.I18N.Shared/I18NAssemblyProvider.cs b/src/Antelcat.I18N.Shared/I18NAssemblyProvider.cs new file mode 100644 index 0000000..ee18ae2 --- /dev/null +++ b/src/Antelcat.I18N.Shared/I18NAssemblyProvider.cs @@ -0,0 +1,24 @@ +using System.Reflection; + +namespace Antelcat.Shared.I18N; + +public static class I18NAssemblyProvider +{ + public static Assembly? Assembly { get; private set; } = null; + + public static void SetAssembly(Assembly assembly) + { + Assembly = assembly; + } + + public static void SetAssembly(Type type) + { + _ = type ?? throw new ArgumentNullException(nameof(type)); + Assembly = type.Assembly; + } + + public static void SetAssembly() where TLangKeys : class + { + SetAssembly(typeof(TLangKeys)); + } +} diff --git a/src/Antelcat.I18N.Shared/I18NExtension.cs b/src/Antelcat.I18N.Shared/I18NExtension.cs index bacf6ad..fb5f2e6 100644 --- a/src/Antelcat.I18N.Shared/I18NExtension.cs +++ b/src/Antelcat.I18N.Shared/I18NExtension.cs @@ -4,6 +4,8 @@ using System.Reflection; using System.Runtime.Serialization; using System.Diagnostics; +using Antelcat.Shared.I18N; + #if WPF using MicrosoftPleaseFixBindingCollection = System.Collections.ObjectModel.Collection; using System.Collections.Generic; @@ -40,8 +42,8 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions; public class I18NExtension : MarkupExtension, IAddChild { private static readonly IDictionary Target; - private static readonly ResourceChangedNotifier Notifier; - private static event CultureChangedHandler? CultureChanged; + private static readonly ResourceChangedNotifier Notifier; + private static event CultureChangedHandler? CultureChanged; private delegate void CultureChangedHandler(CultureInfo culture); @@ -56,13 +58,13 @@ public static CultureInfo Culture static I18NExtension() { var target = new ExpandoObject(); - Target = target; + Target = target; Notifier = new ResourceChangedNotifier(target); #if AVALONIA ExpandoObjectPropertyAccessorPlugin.Register(target); //Register accessor plugin for ExpandoObject var updateActions = new List(); #endif - foreach (var type in Assembly.GetEntryAssembly()?.GetTypes() ?? Type.EmptyTypes) + foreach (var type in (I18NAssemblyProvider.Assembly ?? Assembly.GetEntryAssembly())?.GetTypes() ?? Type.EmptyTypes) { if (!type.IsSubclassOf(typeof(ResourceProviderBase))) continue; #if WPF @@ -104,7 +106,6 @@ static I18NExtension() #endif ); - private static readonly DependencyProperty TargetPropertyProperty = DependencyProperty.RegisterAttached #if AVALONIA @@ -125,7 +126,7 @@ private static void SetTargetProperty(DependencyObject element, DependencyProper private static DependencyProperty GetTargetProperty(DependencyObject element) => (DependencyProperty)element.GetValue(TargetPropertyProperty)!; - #endregion + #endregion Target public static string? Translate(string key, string? fallbackValue = null) { @@ -176,7 +177,7 @@ public I18NExtension() private readonly DependencyObject proxy = new(); /// - /// Resource key, accepts or . + /// Resource key, accepts or . /// If Keys not null, Key will be the template of /// [DefaultValue(null)] @@ -200,7 +201,8 @@ public object? Key #elif AVALONIA Collection #endif - Keys { get; } = new(); + Keys + { get; } = new(); /// /// Same as . @@ -227,8 +229,8 @@ public object? Key { keyBinding = new Binding(key) { - Source = Target, - Mode = BindingMode.OneWay, + Source = Target, + Mode = BindingMode.OneWay, FallbackValue = key, #if AVALONIA Priority = BindingPriority.LocalValue @@ -239,7 +241,7 @@ public object? Key #if WPF keyBinding.UpdateSourceTrigger = UpdateSourceTrigger.Explicit; #endif - keyBinding.Converter = Converter; + keyBinding.Converter = Converter; keyBinding.ConverterParameter = ConverterParameter; return keyBinding; } @@ -247,7 +249,7 @@ public object? Key var ret = new MultiBinding { - Mode = BindingMode.OneWay, + Mode = BindingMode.OneWay, ConverterParameter = ConverterParameter, #if WPF UpdateSourceTrigger = UpdateSourceTrigger.Explicit, @@ -260,7 +262,7 @@ public object? Key var source = new Binding(nameof(Notifier.Source)) { Source = Notifier, - Mode = BindingMode.OneWay + Mode = BindingMode.OneWay }; var isBindingList = new List(); ret.Bindings.Add(source); @@ -275,14 +277,16 @@ public object? Key throw new ArgumentNullException($"Language key should be specified"); ret.Bindings.Add(new Binding(languageBinding.Key) { - Source = Target, - Mode = BindingMode.OneWay, + Source = Target, + Mode = BindingMode.OneWay, FallbackValue = languageBinding.Key }); break; + case BindingBase propBinding: ret.Bindings.Add(propBinding); break; + default: throw new ArgumentException( $"{nameof(Keys)} only accept {typeof(LanguageBinding)} or {typeof(Binding)} current type is {bindingBase.GetType()}"); @@ -293,7 +297,7 @@ public object? Key ret.Converter = new MultiValueLangConverter(isBindingList.ToArray()) { - Converter = Converter, + Converter = Converter, ConverterParameter = ConverterParameter }; return ret; @@ -311,7 +315,7 @@ public override object ProvideValue(IServiceProvider serviceProvider) #if WPF return this; #elif AVALONIA - { + { // Avalonia please fix TargetObject not match if (provideValueTarget.TargetObject is not I18NExtension) return this; var reflect = provideValueTarget.GetType().GetField("ParentsStack"); @@ -348,24 +352,23 @@ public override object ProvideValue(IServiceProvider serviceProvider) ; } - private void I18NExtension_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { #if WPF switch (sender) { case FrameworkElement element: - { - element.DataContextChanged -= I18NExtension_DataContextChanged; - ResetBinding(element); - break; - } + { + element.DataContextChanged -= I18NExtension_DataContextChanged; + ResetBinding(element); + break; + } case FrameworkContentElement element: - { - element.DataContextChanged -= I18NExtension_DataContextChanged; - ResetBinding(element); - break; - } + { + element.DataContextChanged -= I18NExtension_DataContextChanged; + ResetBinding(element); + break; + } } #elif AVALONIA if (sender is not StyledElement element) return; @@ -383,6 +386,7 @@ private void SetTarget(DependencyObject targetObject, DependencyProperty targetP SetTargetProperty(element, targetProperty); element.DataContextChanged += I18NExtension_DataContextChanged; return; + case FrameworkElement element: SetTargetProperty(element, targetProperty); element.DataContextChanged += I18NExtension_DataContextChanged; @@ -408,7 +412,6 @@ private void ResetBinding(DependencyObject element) #endif } - public void AddChild(object value) { if (value is not Binding binding) return; @@ -420,7 +423,6 @@ public void AddText(string key) Keys.Add(new LanguageBinding(key)); } - /// /// use to generate final text /// @@ -432,8 +434,8 @@ private class MultiValueLangConverter( #endif isBindingList) : IMultiValueConverter { - public IValueConverter? Converter { get; set; } - public object? ConverterParameter { get; set; } + public IValueConverter? Converter { get; set; } + public object? ConverterParameter { get; set; } public object? Convert( #if WPF @@ -519,4 +521,4 @@ public void RegisterProvider(ResourceProviderBase provider) public void ForceUpdate() => OnPropertyChanged(nameof(Source)); #endif } -} \ No newline at end of file +}