Search code examples
c#wpfunity-container

The type cannot be used as type parameter 'TTo' in the generic type or method. There is no implicit reference conversion


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?


Solution

  • 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.