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

如何在Ninject解析依赖时添加参数?WPF MVVM实践疑问

WPF MVVM开发:子ViewModel创建优化与工厂模式问题解答

针对你在开发包含UserControls的ItemsControl时遇到的ViewModel创建问题,我来一步步帮你梳理解决方案:

一、简化初始ViewModel列表的写法

你最初的循环代码可以用LINQ链式调用简化,让代码更简洁紧凑:

var viewModels = Enum.GetValues(typeof(DataModel))
                     .Cast<DataModel>()
                     .Select(type => {
                         var vm = ViewModelLocator.Get<IDataViewModel>();
                         vm.Type = type;
                         return vm;
                     })
                     .ToList();

这样就把原来的foreach循环转换成了声明式的LINQ操作,可读性和简洁性都更好。

不过如果想在创建ViewModel时直接传递参数(避免后续手动设置Type属性),工厂模式确实是更优雅的方案,也就是你后来尝试的方向。

二、工厂模式下无法创建新实例的问题

你提到首次调用工厂能创建新实例,但后续调用得到的是同一个对象,这是因为Ninject默认的绑定生命周期是单例(Singleton)——也就是说,一旦创建过一个IDataViewModel实例,后续所有请求都会返回这个实例。

解决方法很简单,只需要在绑定ViewModel时指定Transient生命周期,让Ninject每次请求都创建新的实例:

public class ViewModelModule : NinjectModule {
    public override void Load() {
        // 关键:设置为TransientScope,每次请求都生成新实例
        Bind<IDataViewModel>().To<DataViewModel>().InTransientScope();
        Bind<IViewModelFactory>().ToFactory();
    }
}

另外你自己发现的点非常关键:工厂接口的方法参数必须和ViewModel的构造函数签名完全匹配!
比如你的DataViewModel需要添加一个接收枚举参数的构造函数,这样Ninject的工厂扩展才能自动把参数传递进去:

public class DataViewModel : IDataViewModel {
    // 构造函数必须匹配工厂方法的参数类型
    public DataViewModel(DataModel type) {
        Type = type;
    }

    public DataModel Type { get; set; }
    // 其他接口实现逻辑...
}

这样修改后,工厂调用CreateDataViewModel(type)时,就会自动创建带对应参数的新ViewModel实例,不需要再手动设置Type属性。

三、关于工厂接口的多余方法疑问

你不需要为每个枚举值单独定义一个Create方法!Ninject的工厂扩展会根据方法的参数自动匹配对应的构造函数,一个CreateDataViewModel方法就足够处理所有枚举值的情况,定义多个方法反而会增加冗余,完全没必要。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:49:24