Messenging from DLL to WPF application

Feb 10, 2015 at 12:32 PM
I am stucked with MVVM again. I am trying to send message from method in DLL library which is referenced and used in WPF application. This is for showing UI dialog from non-UI data service. It looks like message can not be delivered from library to application, even if application is correctly registered as recipient. I hope it is not something like both codes are running in different application domains or something similarly dreadful, which is preventing to use cool MVVM Light messenging. How to solve this problem?
Coordinator
Feb 10, 2015 at 12:37 PM
Hi,

OK first the good news: You can absolutely message from a DLL to a WPF app, that works.

If in your case it fails, it could be a few things.
  • The DLL is not loaded in the same AppDomain as the main app. That would be surprising, as it is not very standard.
  • Some exception preventing the message to be sent. Maybe some threading issue?
If you provide a repro, I am happy to take a look.

Cheers
Laurent
Feb 10, 2015 at 1:17 PM
Thats good news. My application is quite complex now, so I will try to describe what is happening.
  1. Application starts
  2. Main window loads, in its XAML is defined DataContext as MainViewModel located using ViewModelLocator.
  3. MainViewModel loads some data using repository and this repository gets user credentials for logging into database by connection service.
  4. When connection service's GetConnectionString is called, it should send request message to main window to show login dialog and return UserID and Password back using callback.
Part 4 is not working, when I set breakpoint on main window's ProcessMessage method, execution never arrive there. Here is key part of my connection service:
Public Function GetConnectionString(ByRef connectionString As String) As Boolean
  Dim message As New NotificationMessageAction(Of Object)(Me,
    MessageIdentifiers.UserCredentialsRequest,
    AddressOf ParseCredentials)
  Messenger.Default.Send(Of NotificationMessageAction(Of Object))(message)
  REM I expect that execution stops here until message is processed in WPF application's ProcessMessage method.
  sqlCSBuilder.UserID = _userId
  sqlCSBuilder.Password = _password
  entityCSBuilder.ProviderConnectionString = sqlCSBuilder.ToString()
  _connectionString = entityCSBuilder.ToString()
End Function
Private Sub ParseCredentials(credentials As Object)
  If (Not TypeOf credentials Is String) OrElse (credentials Is Nothing) Then Throw New ArgumentNullException("credentials")
  Dim values = DirectCast(credentials, String).Split(New String() {","}, StringSplitOptions.RemoveEmptyEntries)
  If values.Length <> 2 Then Throw New ArgumentNullException("credentials")
  _userId = values(0)
  _password = values(1)
End Sub
Coordinator
Feb 10, 2015 at 3:01 PM
Hi,

If you put a breakpoint in both the location where the Messenger.Default is registered for the type of NotificationMessageAction, and inside ParseCredentials, are these breakpoints hit or not?

Also, is there any asynchronous operation going on between the moment where you send the message and the moment where the callback is called?

Thanks
Laurent
Feb 11, 2015 at 7:01 AM
Edited Feb 11, 2015 at 7:03 AM
Hi,
breakpoint is hit at Messenger.Default.Register, Messenger.Default.Send, but not in ParseCredentials callback method, which is key method to get credentials from UI.
No asynchronous operations anywhere in application.

Thanks for help!
Coordinator
Feb 11, 2015 at 7:48 AM
Is there any way to share a repro?

Thanks,
Laurent
Feb 11, 2015 at 8:23 AM
What do you mean by repro? I am sure that it will not be reproductors.
Coordinator
Feb 11, 2015 at 9:39 AM
I mean a simple way to reproduce the issue, so that I can investigate what is going on. If you send me the full app, it is probably too complex (even assuming that you could share this code). If you have a simple way to show the issue, I am happy to debug it.

Cheers
Laurent
Feb 16, 2015 at 12:48 PM
Messenger.Default.Send is not working asynchronously, right? So I expect that sqlCSBuilder.UserID = _userId will be executed after message is processed in MainWindow. But because it is not processed in MainWindow at all, exception is thrown on this line, because _userId is not set by ParseCredentials callback method...
Feb 20, 2015 at 11:11 AM
It was caused by inconsistent versions of MVVM Light. Solved by NuGet package. Thanks going to L. Bugnion.
Coordinator
Feb 20, 2015 at 11:16 AM
Happy it solved your issue, thanks for following up!

Cheers
Laurent