jDave1984
jDave1984

Reputation: 972

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?

Upvotes: 1

Views: 1614

Answers (1)

Nkosi
Nkosi

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

Related Questions