Reputation: 972
I'm currently trying to use Unity to inject ViewModels into my WPF Application.
I tend to use a ViewModelLocator
class to store all of my ViewModels in one area, for quick navigation between them
I've split up my app into four projects:
KeystonePP.Models
- Holds my EF Model
KeystonePP.Startup
- Main startup logic
KeystonePP.ViewModels
- ViewModels and their interfaces
KeystonePP.Views
- Views
I have an IViewModelLocator
interface in a separate project: KeystonePP.ViewModels
public interface IViewModelLocator
{
// No code here. Just a contract
}
This is implemented by my ViewModelLocator
class
public class ViewModelLocator : ObservableObject, IViewModelLocator
{
// Lots of code here
}
In my KeystonePP.Startup
project, I have adjusted my MainWindow.xaml.cs
constructor as such:
public partial class MainWindow : Window
{
public MainWindow (IViewModelLocator viewModelLocator)
{
InitializeComponent();
DataContext = viewModelLocator;
}
}
However, when I attempt the following code in App.xaml.cs
, I'm getting an error warning:
public partial class App : Application
{
/// <summary>
/// Startup Logic for App
/// </summary>
/// <param name="e"></param>
protected override void OnStartup (StartupEventArgs e)
{
base.OnStartup(e);
IUnityContainer container = new UnityContainer();
container.RegisterType<IViewModelLocator, MainWindow>();
}
}
I get the following error:
The type 'KeystonePP.Startup.MainWindow' cannot be used as type parameter 'TTo' in the generic type or method 'UnityContainerExtensions.RegisterType(IUnityContainer, params InjectionMember[])'. There is no implicit reference conversion from 'KeystonePP.Startup.MainWindow' to 'KeystonePP.ViewModels.Utility.Interfaces.IViewModelLocator'.
Have I gone too complicated, or am I missing something simple setting up Unity?
Upvotes: 1
Views: 1614
Reputation: 247393
You want to register abstractions with their implementations.
IUnityContainer container = new UnityContainer();
container.RegisterType<IViewModelLocator, ViewModelLocator>();
container.RegisterType<MainWindow>();
that way when you call to resolve MainWindow
var mainWindow = container.Resolve<MainWindow>();
mainWindow.Show();
the container will know how to inject the implementation based on the abstraction when resolving.
Upvotes: 2