我需要通过调度器来更新UI:
container.RegisterType<Dispatcher>().AsSelf();
container.Register(c => new MyViewModel(c.Resolve<Dispatcher>(), ...some other arguments)).As<IMyViewModel>();
但由于它是静态的,当我执行container.Build();
时,我会得到这个异常:
Autofac.Core.Activators.Reflection.NoConstructorsFoundException:
'No accessible constructors were found for the type 'System.Windows.Threading.Dispatcher'.'
在我的视图模型中,我通常像_dispatcher?.Invoke('some code');
一样使用它。
我曾想过将其从视图模型构造函数中删除,并在其中只执行_dispatcher = Dispatcher.CurrentDispatcher;
,但由于我使用线程,我不确定这是否是使用它的最佳方式。
通过RegisterType
注册调度程序,Autofac将在每次尝试解决调度程序时创建一个新实例。由于Dispatcher
只有一个private
无参数构造函数,因此会出现没有可访问构造函数的错误。一般来说,您不会自己创建调度器。
在线程上创建Dispatcher时,即使Dispatcher已关闭,它也将成为唯一可以与该线程关联的调度程序。
如果您尝试获取当前线程的CurrentDispatcher,而Dispatcher未与该线程关联,则会创建一个Dispatcher。创建DispatcherObject时也会创建Dispatcher。。如果在后台线程上创建调度程序,请确保在退出线程之前关闭该调度程序。
可以使用Application.Current.Dispatcher
访问用户界面线程的调度器。由于此调度器已经存在,并且是唯一的实例,因此必须将此实例注册为singleton。
container.RegisterInstance(Application.Current.Dispatcher).AsSelf();
然后,您可以通过类型Dispatcher
在任何位置解析它,因为您注册了它AsSelf
。
var dispatcher = container.Resolve<Dispatcher>();
关于视图模型的单元测试,通过Dispatcher
是不幸的。它没有实现一个合适的接口来模拟它,并且是sealed
,所以你可以派生它
- 在单元测试中使用WPF Dispatcher
- 如何测试像Application.Current.Dispatcher这样使用Singleton的代码