I have been trying to set up dependency injection in a wpf application using Unity, but can't seem to fully understand how the views and viewmodels should be set up.
Have looked into another SO post --> Wpf Unity but can't seem to understand it quite yet. I have used Unity before, but just in a MVC application, so I know how to inject it in the contructors.
Here is my views and viewModels in the application.
Views:
MainWindow.xaml
BookingView.xaml
ContactDetailsView.xaml
ReservationsView.xaml
ViewModels:
MenuViewModel (MainWindow uses this viewModel)
BookingViewModel
ContactViewModel
ReservationsViewModel
My ViewModels all have Interfaces implemented, like IMenuViewModel, should the view also have an interface?
I guess that since the MainWindow is the starting point, it should be here to register the container right?
Have found something, but not sure if I have done it right. Here is what I have done so far!
1: Using startup method in app.cs
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
IUnityContainer container = new UnityContainer();
container.RegisterType<IViewMainWindowViewModel, MainWindow>();
container.RegisterType<IViewMainWindowViewModel, MenuViewModel>();
var mainWindow = container.Resolve<MainWindow>(); // Creating Main window
mainWindow.Show();
}
}
2: Remove uri from start up.
3: Make IViewMainWindowViewModel interface in MainWindow class, the interface is empty.
public interface IViewMainWindowViewModel
{
}
4: Make a reference to this interface in the MainWindow
public partial class MainWindow : Window, IViewMainWindowViewModel
{
public MainWindow(IViewMainWindowViewModel viewModel)
{
InitializeComponent();
DataContext = viewModel;
}
5: Also for the MenuViewModel
public class MenuViewModel : IViewMainWindowViewModel
{
Code not shown!
}
This will not even start the application..
My MainWindow class look like this:
public interface IViewMainWindowViewModel
{
}
public partial class MainWindow : Window, IViewMainWindowViewModel
{
public MainWindow(IViewMainWindowViewModel viewModel)
{
InitializeComponent();
DataContext = viewModel;
}
App class now look like this:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
IUnityContainer container = new UnityContainer();
container.RegisterType<IViewMainWindowViewModel, MainWindow>();
container.RegisterType<IViewMainWindowViewModel, MenuViewModel>();
container.Resolve<MainWindow>().Show();
//Do the same actions for all views and their viewmodels
}
I get an exception on this line when running the application
container.Resolve<MainWindow>().Show();
In my MenuViewModel it has two command which will open two views, do I then need to inject those views in the MenuViewModel's constructor or can you just make another empty interface between MenuViewModel and BookingView as an example?
Let me show an example with explanations just for your MainWindows, as for the rest views and viewmodels steps to do are the same.
At first, you should create a contract between View and ViewModel. It shoud be some interface and let it call IViewMainWindowViewModel (keep in mind that name has to be different for other view and viewModels, for example IViewBookingViewViewModel):
public interface IViewMainWindowViewModel
{
/*This interface should not have any methods or commands. It is just
contract between View and ViewModels and helps to decide to Unity
container what it should inject(appropriate viewModel to necessary
View)*/
}
then in your viewmodel we should implement this interface:
public MenuViewModel:IViewMainWindowViewModel
{}
The view should inject this interface MainWindows.xaml.cs:
public partial class MainWindows : UserControl, IContentAView
{
public MainWindows(IViewMainWindowViewModel viewModel)
{
InitializeComponent();
DataContext = viewModel;
}
}
Delete StartupUri and override a method OnStartup in App.xaml.cs:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
IUnityContainer container = new UnityContainer();
container.RegisterType<IViewMainWindowViewModel, MainWindow>();
container.RegisterType<IViewMainWindowViewModel, MainWindowViewModel >();
container.Resolve<MainWindow>().Show();
//Do the same actions for all views and their viewmodels
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With