You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

IOptionsWritable.Update()在WinForm类中无法写入json文件问题

问题原因

核心是你运行时用的FormConfiguration实例根本不是DI容器解析出来的,没拿到合法的IOptionsWritable<SomeSectionClass>实例,调用Update时自然写不进配置,而IOptionsWriter库内部做了容错,这种情况不会抛异常。
90%的情况都是你打开配置窗体的时候直接写了new FormConfiguration()手动创建实例,完全没走DI注入流程。WinForms窗体为了适配设计器一般都会留无参构造,你手动new的时候调用的就是这个无参构造,类里的_someWritableOptions字段要么是null(你可能加了空值判断跳过了执行,所以没抛空引用异常),要么是你为了过编译手动塞了个空的占位实现,根本没绑定到实际加载了appsettings.json的配置对象,Update操作等于啥也没干。
剩下10%的可能是你用的IOptionsWriter版本默认把IOptionsWritable注册为Scoped生命周期,你在Program里手动建的scope在主窗体运行后被释放,后续拿到的失效实例调用Update会静默失败。
你虽然在DI里注册了services.AddSingleton<IFormConfiguration, FormConfiguration>(),但只要你没从容器拿实例、自己new窗体,这个注册就完全不生效。

修复步骤
  1. 先验证实例一致性
    在SomePresenter.OnSomeEvent和FormConfiguration.BtnSave_OnClick里分别打调试断点,运行时看两个方法里_someWritableOptions的哈希码,两个值不一样就坐实是手动new窗体的问题。
  2. 改掉手动new窗体的逻辑
    所有用到FormConfiguration的地方都不许手动new,统一从DI容器获取:
  • 在主窗体FormMain的构造函数里直接注入IFormConfiguration,存成私有字段,要打开配置页的时候直接对这个字段调用Show/ShowDialog就行。
  • 要是必须留无参构造给设计器用,就加个DesignMode判断,只有设计器运行的时候才走无参构造,运行时全走DI的带参构造,别在无参构造里给_someWritableOptions塞无效的占位对象。
  1. (可选,兼容旧版库)修改服务生命周期
    调用ConfigureWritable的时候手动指定生命周期为单例,避免Scoped实例释放导致的写入失败:
services.ConfigureWritable<SomeSectionClass>("SomeSection", ServiceLifetime.Singleton);
  1. 不用排查文件权限问题,毕竟你在Presenter里能正常写入,说明文件本身和路径配置都没有问题。

内容的提问来源于stack exchange,提问作者Maakarov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 04:15:51