首页 > 其他分享 >Prism使用Options选项

Prism使用Options选项

时间:2023-12-05 19:22:06浏览次数:22  
标签:选项 container Options public Prism 添加 config class

Options是微软提供的选项模块,该模块依赖于容器使用。除了微软的IServiceCollection,当然也可以使用其它的依赖注入容器。本文演示如何在prism中使用Options。

创建应用项目

创建一个Avalonia应用(或其它类型应用),然后使用NuGet包管理器添加Prism.DryIoc.Avalonia包。创建Views和ViewModels文件夹,将MainWindow移动到Views文件夹中(注意修改namespace),在ViewModels文件夹中创建MainWindowViewModel,以便Prism自动绑定ViewModel。

public partial class App : PrismApplication
{
    public override void Initialize()
    {
        AvaloniaXamlLoader.Load(this);
        base.Initialize();
    }

    protected override AvaloniaObject CreateShell()
    {
        return Container.Resolve<MainWindow>();
    }

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.Register<MainWindow>();
    }
}

添加Options功能

  • 首先使用NuGet添加Microsoft.Extentions.Options和Microsoft.Extensions.Options.ConfigurationExtensions。使用json配置文件进行测试,因此再添加上Microsoft.Extensions.Configuration.Json及Microsoft.Extensions.Configuration.Binder。

  • 添加Options静态类,提供DefaultName:

public static class Options
{
    public static readonly string DefaultName = string.Empty;
    internal const DynamicallyAccessedMemberTypes DynamicallyAccessedMembers =
        DynamicallyAccessedMemberTypes.PublicParameterlessConstructor;
}
  • 由于UnnamedOptionsManager为内部类,无法直接使用,因此添加一个UnnamedOptionsManager类,实现IOptions<>接口,直接拷贝源码即可:
public class UnnamedOptionsManager<[DynamicallyAccessedMembers(Options.DynamicallyAccessedMembers)] TOptions> :
    IOptions<TOptions>
    where TOptions : class
{
    private readonly IOptionsFactory<TOptions> _factory;
    private volatile object _syncObj;
    private volatile TOptions _value;

    public UnnamedOptionsManager(IOptionsFactory<TOptions> factory) => _factory = factory;

    public TOptions Value
    {
        get
        {
            if (_value is TOptions value)
                return value;

            lock (_syncObj ?? Interlocked.CompareExchange(ref _syncObj, new object(), null) ?? _syncObj)
            {
                return _value ??= _factory.Create(Options.DefaultName);
            }
        }
    }
}
  • 添加OptionsPrismExtensions扩展类,添加AddOptions扩展方法,将选项泛型接口、工厂、缓存注册到容器中。工厂注册为瞬时,其它注册为单例。客户端不需要添加IOptionsSnapshot,只添加IOptions<>和IOptionsMonitor<>即可,前者获取选项不会监听修改,后者可以监听选项修改:
public static class OptionsPrismExtensions
{
    public static IContainerExtension AddOptions(this IContainerExtension container)
    {
        ArgumentNullException.ThrowIfNull(container, nameof(container));

        container.RegisterSingleton(typeof(IOptions<>), typeof(UnnamedOptionsManager<>));
        container.RegisterSingleton(typeof(IOptionsMonitor<>), typeof(OptionsMonitor<>));
        container.Register(typeof(IOptionsFactory<>), typeof(OptionsFactory<>));
        container.RegisterSingleton(typeof(IOptionsMonitorCache<>), typeof(OptionsCache<>));
        return container;
    }
}
  • 添加OptionsConfigurationPrismExtensions扩展类,提供Configuration相关的扩展方法,可以直接将选项和配置Section进行绑定:
public static class OptionsConfigurationPrismExtensions
{
    public static IContainerExtension Configure<[DynamicallyAccessedMembers(
        DynamicallyAccessedMemberTypes.All)] TOptions>(this IContainerExtension container, 
        IConfiguration config) where TOptions : class
        => container.Configure<TOptions>(Options.DefaultName, config, _ => { });

    public static IContainerExtension Configure<[DynamicallyAccessedMembers(
        DynamicallyAccessedMemberTypes.All)] TOptions>(this IContainerExtension container, 
        string name, IConfiguration config, Action<BinderOptions> configureBinder)
        where TOptions : class
    {
        ArgumentNullException.ThrowIfNull(container, nameof(container));
        ArgumentNullException.ThrowIfNull(config, nameof(config));
    
        container.AddOptions();
        container.RegisterInstance<IOptionsChangeTokenSource<TOptions>>(
            new ConfigurationChangeTokenSource<TOptions>(name, config));
        container.RegisterInstance<IConfigureOptions<TOptions>>(
            new NamedConfigureFromConfigurationOptions<TOptions>(name, config, configureBinder));
    
        return container;
    }
}

使用

  • 添加一个settings.json配置文件,设置属性复制到输出目录:如果较新则复制:
{
  "Test": {
    "Name": "louzi",
    "Age": 18,
    "Sex": "Male"
  }
}
  • 添加Test对应的Option实体:
public class TestOption
{
    public string Name { get; set; }

    public int Age { get; set; }

    public Gender Sex { get; set; }
}

public enum Gender
{
    Male,
    Female
}
  • 创建IConfiguration并绑定到选项:
// App
protected override IContainerExtension CreateContainerExtension()
{
    var container =  base.CreateContainerExtension();

    IConfiguration config = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("settings.json", optional: true, reloadOnChange: true).Build();
    container.AddOptions().Configure<TestOption>(config.GetSection("Test"));

    return container;
}
  • ViewModel中通过依赖注入获取选项:
public class MainWindowViewModel : BindableBase
{
    private string _name;
    private int _age;
    private Gender _sex;

    public MainWindowViewModel(IOptions<TestOption> options)
    {
        var testOption = options.Value;
        _name = testOption.Name;
        _age = testOption.Age;
        _sex = testOption.Sex;
    }

    public string Name { get => _name; set => SetProperty(ref _name, value); }

    public int Age { get => _age; set => SetProperty(ref _age, value); }

    public Gender Sex { get => _sex; set => SetProperty(ref _sex, value); }
}
  • View中显示
<Grid RowDefinitions="1*,1*,1*" ColumnDefinitions="1*,1*">
	<TextBlock Text="Name: " TextAlignment="Right"/>
	<TextBlock Text="{Binding Name}" Grid.Column="1"/>
	<TextBlock Text="Age: " Grid.Row="1" TextAlignment="Right"/>
	<TextBlock Text="{Binding Age}" Grid.Row="1" Grid.Column="1"/>
	<TextBlock Text="Sex: " Grid.Row="2" TextAlignment="Right"/>
	<TextBlock Text="{Binding Sex}" Grid.Row="2" Grid.Column="1"/>
</Grid>

项目结构及运行效果如下图:

标签:选项,container,Options,public,Prism,添加,config,class
From: https://www.cnblogs.com/louzixl/p/17877961.html

相关文章

  • WPF 选项卡 控件 美化
    WPF选项卡控件美化效果: 样式<LinearGradientBrushx:Key="TabItem.Selected.BordernCjh"StartPoint="0,0"EndPoint="0,1"><GradientStopColor="#FFE8A6"Offset="0.07"/><GradientStopColor=&......
  • MySQL 配置选项和变量间的关系
    MySQL变量MySQL中的变量主要分为两大类,用户变量和系统变量。1、用户变量用户变量是用户自定义的变量,用户变量以@符号开头,通过set或者select可以给用户变量赋值。用户变量是属于会话级别的变量,变量的值只在当前会话中有效,当会话结束时,这些变量的值就会丢失。例如:SET@myVar......
  • wpf学习 Prism 使用入门
    一、手动添加安装包Prism.DryIocapp.xaml.cs修改继承基类为:PrismApplication实现其中的抽象成员:CreateShell用于指定启动的窗口类1publicpartialclassApp:PrismApplication2{3protectedoverrideWindowCreateShell()4{5......
  • Wpf Prism 导航(参数传递,路由守卫,路由记录)
    十年河东,十年河西,莫欺少年穷学无止境,精益求精1、新建项目wpfApp5,添加Nuget引用,并初始化App.xaml及cs类 app.xaml如下:<Prism:PrismApplicationx:Class="WpfApp5.App"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="......
  • this.$refs —— 只适用于选项式 API
    只适用于选项式API的情况下this.$refs是用于在Vue组件中访问子组件或者DOM元素的一种方式。通常,在模板中可以使用ref属性为子组件或者DOM元素指定引用,然后通过this.$refs来访问这些引用在选项式API(OptionsAPI)中,比如在methods、mounted、created等生命周......
  • 07.Android开发者选项
    1.开启开发者选项点击设置点击关于手机连续点击N次MIUI版本2.常用选项开启开发者选项不锁定屏幕USB调试选择模拟位置信息应用显示触摸操作指针位置调试GPU过渡绘制显示所有“应用程序无响应” ......
  • win11右键选项的强迫症治理
    系统升级到win11之后,发现最难用的就是,每次右键重命名文件名的时候,都需要点击下显示更多选项。每次都是这样,步骤多一步之后这个人都不舒服了。于是就这样一天两天然后一个月过去了,今天无意看到一个修改方法,可直接回到win10的右键方式,于是欣喜若狂的我果断试了下,效果很满意,在此给......
  • idea修改idea64.exe.vmoptions导致打不开问题(破解后的idea)
    问题原因是在idea中改了idea64.exe.vmoptions配置,导致idea打不开。网上帖子很多说是C盘appdata里面的缓存idea64.exe.vmoptions文件删除或者更改成跟安装目录一样的就行了。 idea用了激活工具方式解决:如果用了激活工具,激活工具目录里一般都会有idea64.exe.vmoptions同名......
  • 直播平台源代码,实现一个简单的带tabs选项卡切换的首页导航功能
    直播平台源代码,实现一个简单的带tabs选项卡切换的首页导航功能 package.json: { "name":"angular-router", "version":"0.0.0", "scripts":{  "ng":"ng",  "start":"ngserve",  "bui......
  • Wpf Prism初体验
    十年河东,十年河西,莫欺少年穷学无止境,精益求精1、项目引入 Prism.DryIoc  2、规则说明窗体必须放在Views文件夹下而且必须以View结尾,ViewModel必须放在ViewModels文件夹下面,文件必须以ViewModel结尾。在prism框架下,可以不为窗体设定数据上下文,但,在窗体中必须显示声明:......