I would suggest to use a controller in this scenario, say DI'ed dialogController backed up with a dialog shell. The source viewmodel(ie from where the request to open a dialog is originating) will make a call to dialogController.ShowDialog(<<ViewNameToHostInRegion>>,<<RegionName>>)
.
In Order to transfer the data to and from the dialog and sourceview you can use MessageBus. So essentially when you invoke the ShowDialog() you populate the messagebus, and when the close command of target View(The view hosted in Dialog shell) invoked - say in "Select" button -- Let the target view add/update the messagebus. So that source view model can work with updated data.
It has got many advantages :
1) Your source view works with dialog controller as BlackBox. ie it doesnt aware of what exactly the Dialog view is doing.
2) The view is being hosted in Dialog Shell -- so you can reuse the dialog again and again
3) Unit testing of source view is limited to test the actual functionality of the current viewmodel, and not to test the dialog view\view model.
One heads-up which I came across with this one is, while creating the test cases you may need to write testable Dialog controller which do not show the actual dialog while running the testcases in bunch. So you will need to write a TestableDialogController in which ShowDialog does nothing (Apart from deriving from IDialogController and provide blank implementation of ShowDialog().
Following is the psudeo code :
LocalMessageBus.AddMessage(<MessageKey>,<MessageActualContentAsObject>);
dialogController.ShowDialog(<TargetViewName_SayEmployeeList>);
Employee selectedEmployee = LocalMessageBus.GetMessage(<MessageKey>) as Employee;
if (selectedEmployee != null)
{
//doSomework with selected employee
}