Plugin Configuration File
Depends on ShadowObservableConfig
FileExt
optional: .yaml
or .json
1. Create Configuration Class (using yaml as example)
csharp
using ShadowObservableConfig.Attributes;
using System.Collections.ObjectModel;
[ObservableConfig(FileName = "app_config", FileExt = ".yaml", DirPath = "config", Description = "Application configuration", Version = "1.0.0")]
public partial class AppConfig
{
[ObservableConfigProperty(Name = "AppName", Description = "Application name")]
private string _appName = "My App";
[ObservableConfigProperty(Name = "IsEnabled", Description = "Whether enabled")]
private bool _isEnabled = true;
[ObservableConfigProperty(Name = "MaxRetryCount", Description = "Maximum retry count")]
private int _maxRetryCount = 3;
[ObservableConfigProperty(Name = "Settings", Description = "Application settings")]
private AppSettings _settings = new();
[ObservableConfigProperty(Name = "Features", Description = "Feature list")]
private ObservableCollection<string> _features = new();
}
[ObservableConfig(Description = "Application settings", Version = "1.0.0")]
public partial class AppSettings
{
[ObservableConfigProperty(Name = "Theme", Description = "Theme")]
private string _theme = "Light";
[ObservableConfigProperty(Name = "Language", Description = "Language")]
private string _language = "zh-CN";
}
2. Using in WinUI 3 (using yaml as example)
csharp
// App.xaml.cs
public App()
{
InitializeComponent();
ShadowObservableConfig.GlobalSetting.Init(ApplicationData.Current.LocalFolder.Path,
[
new ShadowObservableConfig.Yaml.YamlConfigLoader()
]);
}
csharp
public sealed partial class MainPage : Page
{
public AppConfig ViewModel { get; } = AppConfig.Load();
public MainPage()
{
this.InitializeComponent();
ViewModel.ConfigChanged += OnConfigChanged;
}
private void OnConfigChanged(object? sender, ConfigChangedEventArgs e)
{
Debug.WriteLine($"Configuration item '{e.FullPropertyPath}' changed: {e.OldValue} -> {e.NewValue}");
}
}
3. XAML Data Binding
xml
<Page x:Class="MyApp.MainPage">
<StackPanel>
<TextBox Header="Application name"
Text="{x:Bind ViewModel.AppName, Mode=TwoWay}" />
<CheckBox Content="Enable application"
IsChecked="{x:Bind ViewModel.IsEnabled, Mode=TwoWay}" />
<NumberBox Header="Maximum retry count"
Value="{x:Bind ViewModel.MaxRetryCount, Mode=TwoWay}" />
<ComboBox Header="Theme"
SelectedItem="{x:Bind ViewModel.Settings.Theme, Mode=TwoWay}">
<ComboBoxItem Content="Light" />
<ComboBoxItem Content="Dark" />
</ComboBox>
</StackPanel>
</Page>
📚 Detailed Documentation
Property Description
ObservableConfigAttribute
FileName
: Configuration file name (without extension). Not filling this field means the current class is an internal classFileExt
: Configuration file extensionDirPath
: Configuration file directory (default is "config")Description
: Configuration descriptionVersion
: Configuration version
ObservableConfigPropertyAttribute
Name
: Property name in configuration fileDescription
: Property descriptionAlias
: Property alias (only valid in yaml)AutoSave
: Whether to auto-save (default is true)
Supported Data Types
- Basic types:
string
,int
,double
,bool
,DateTime
, etc. - Enum types: Any
enum
type - Collection types:
ObservableCollection<T>
- Nested objects: Other classes marked with
[ObservableConfig]
Auto-generated Methods
The source generator will automatically generate for each configuration class:
- Public property accessors
Load()
static methodSave()
methodAfterConfigInit()
partial method (can be overridden)
🔧 Advanced Usage
Custom Configuration Loader
csharp
public class CustomConfigLoader : IConfigLoader
{
public T Load<T>(string filePath) where T : class
{
// Custom loading logic
return JsonSerializer.Deserialize<T>(File.ReadAllText(filePath));
}
public void Save<T>(T config, string filePath) where T : class
{
// Custom saving logic
File.WriteAllText(filePath, JsonSerializer.Serialize(config, new JsonSerializerOptions { WriteIndented = true }));
}
}
Remember to set it in ShadowObservableConfig.GlobalSetting.Init
after customizing.
Configuration Initialization Callback
csharp
[ObservableConfig(FileName = "my_config")]
public partial class MyConfig
{
[ObservableConfigProperty(Name = "Value")]
private string _value = "default";
partial void AfterConfigInit()
{
// Initialization logic after configuration loading
Console.WriteLine($"Configuration loaded: {Value}");
}
}