Reputation: 3647
I am trying to create a module with PRISM and right now I set the DataContext inside the View which means I can only use a Parameterless constructor, but that means I cant use dependency injection (I use Unity) in the constructor which I would like
If it is possible I would like neither the view or the vm to know each other and want to use something like
private void RegisterServices()
{
var employeeViewModel = new EmployeeViewModel();
_container.RegisterType<IEmployeeViewModel, EmployeeViewModel>();
_container.RegisterType<EmployeeView>();
EmployeeView.Datacontext = employeeViewModel;
}
Which I would register in the EmployeeModule
Is this possible or should I use code behind?
Upvotes: 4
Views: 4037
Reputation: 1880
Prism documentation gives you an option
Often, you will find it useful to define a controller or service class to coordinate the instantiation of the view and view model classes. This approach can be used with a dependency injection container, such as MEF or Unity, or when the view explicitly creates its required view model.
For my module I would do the following
Create an interface for service inside module
public interface ICustomModuleUiService
{
void ShowMainView();
void ShowExtraView();
}
Production implementation in the same module:
class CustomModuleUiService : ICustomModuleUiService
{
private readonly IEventAggregator _eventAggregator;
public CustomModuleUiService(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
}
public void ShowMainView()
{
var ddsViewModel = new DdsViewModel(_eventAggregator, this);
DdsForm form = new DdsForm();
form.DataContext = ddsViewModel;
form.Show();
}
public void ShowExtraView()
{
//some code here
}
}
And finally module code
[ModuleExport("DssModule", typeof(DssModuleImpl))]
public class DssModuleImpl : IModule
{
private readonly IEventAggregator _eventAggregator;
private ICustomModuleUiService _uiService;
[ImportingConstructor]
public DssModuleImpl(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
_uiService = new CustomModuleUiService(_eventAggregator);
}
public void Initialize()
{
_eventAggregator.GetEvent<OpenDdsFormEvent>().Subscribe(param => _uiService.ShowMainView());
}
}
Using this approach I'll get
Upvotes: 1
Reputation: 14929
You may pass the interface of ViewModel
to the View
in the constructor. This way, View
only knows the interface of ViewModel
and ViewModel
knows nothing about the View
.
Ex.
public class EmployeeView : UserControl
{
public EmployeeView(IEmployeeViewModel vm)
{
this.DataContext = vm; //// better to set the ViewModel in the Loaded method
}
}
Refer to this blog post for multiple approaches of MVVM instantiation.
Upvotes: 2