Reputation: 610
I need to pass the dispatcher to update the UI:
container.RegisterType<Dispatcher>().AsSelf();
container.Register(c => new MyViewModel(c.Resolve<Dispatcher>(), ...some other arguments)).As<IMyViewModel>();
But since it's static, when I do container.Build();
I get this exception:
Autofac.Core.Activators.Reflection.NoConstructorsFoundException:
'No accessible constructors were found for the type 'System.Windows.Threading.Dispatcher'.'
In my viewmodels I usually use it like _dispatcher?.Invoke('some code');
.
I thought about removing it from the viewmodels contructors and in them just do _dispatcher = Dispatcher.CurrentDispatcher;
, but since I'm working with threads im not sure if it is the best way to use it.
Upvotes: 0
Views: 377
Reputation: 22119
By registering a dispatcher by RegisterType
, Autofac will create a new instance of a dispatcher each time you try to resolve it. Since a Dispatcher
only has an private
parameterless constructor, you get the error that there is no accessible constructor. In general, you do not create dispatchers yourself.
When a Dispatcher is created on a thread, it becomes the only Dispatcher that can be associated with the thread, even if the Dispatcher is shut down.
If you attempt to get the CurrentDispatcher for the current thread and a Dispatcher is not associated with the thread, a Dispatcher will be created. A Dispatcher is also created when you create a DispatcherObject. If you create a Dispatcher on a background thread, be sure to shut down the dispatcher before exiting the thread.
The dispatcher of the user interface thread can be accessed using Application.Current.Dispatcher
. Since this dispatcher already exists and is a unique instance, you have to register this instance as singleton.
container.RegisterInstance(Application.Current.Dispatcher).AsSelf();
Then you can resolve it anywhere by the type Dispatcher
, because you registered it AsSelf
.
var dispatcher = container.Resolve<Dispatcher>();
Regarding unit testing your view models, passing a Dispatcher
is unfortunate. It does not implement a suitable interface to mock it and is sealed
, so you can derive it. However, there are solutions:
Upvotes: 2