3

I have Unity 2.0 working well within the App.xaml.cs to register and resolve within that class.

The question I have is regarding a best practice.

I have a number of User Controls and other classes that also need to resolve some of the same and new Interface <-> implementations. The problem is theres no way to access the Unity container I created in the App.xaml.cs.

I cannot use constructor or property injection to pass on the container reference.

  1. Just too many (its a large project)
  2. The user controls are added via xaml
  3. There are several very loosely related "modules" in the project that can share the same container config.

I would rather not re-create the container from a config file in each object that needs access to the container.

Any best practice suggestions when the same container is needed as a service in various "modules" of the same assembly?

Thanks.

IUnknown
  • 2,596
  • 4
  • 35
  • 52
  • You say "user controls are added via XAML": which parts are you aiming to inject? Usually you would possibly inject your View Models and definitely your "modules"/controllers/services. – Reddog Mar 01 '11 at 19:22
  • I would like to using Unity to add the VM and to resolve a data provider or service provider in the ViewModels. – IUnknown Mar 01 '11 at 20:38

1 Answers1

4

I believe bringing together Controls and IoC is pain in the ... in the code at least. Probably somebody will argue but IMO the best practice to avoid this pain is MVVM. You will have viewModels which you can freely construct using Unity and inject everything you need into them. You will have views with bindings to viewModels with no reason to know anything abound inversion of control.

UPDATE: Based on comment:

App.xaml.cs:

    private void HandleStartup(object sender, StartupEventArgs e)
    {
        var container = CreateContainer(); // create IoC container
       var mainViewModel = container.Resolve<MainViewModel>();
        var shell = new Shell { DataContext = mainViewModel }; // main View
        MainWindow = shell;
        shell.Show();
    }

Shell XAML example:

<UserControl>
     <StackPanel>
          <ContentPresenter Content="{Binding ViewModel1}" />
          <ContentPresenter Content="{Binding ViewModel2}" />
          <ContentPresenter Content="{Binding ViewModel3}" />
     </StackPanel>
</UserControl>

MainViewModel:

public class MainViewModel
{
     public ViewModel1 ViewModel1 { get; private set; }
     public ViewModel2 ViewModel2 { get; private set; }
     public ViewModel3 ViewModel3 { get; private set; }

     // this will be handled by IoC container
     public MainViewModel(ViewModel1 viewModel1, ViewModel2 viewModel2, ViewModel3 viewModel3)
    {
        ViewModel1 = viewModel1;
        ViewModel2 = viewModel2;
        ViewModel3 = viewModel3;
    }

In this way your views will be unaware of IoC and everything you want in viewModels will be successfully injected.

UPDATE2 DataTemplating which brings Views and ViewModels together:

App.xaml

<Application.Resources>
    <DataTemplate DataType="{x:Type local:ViewModel1}">
        <View1 />
    </DataTemplate>
</Application.Resources>
Snowbear
  • 16,924
  • 3
  • 43
  • 67
  • I am using MVVM - the views are implemented as User Controls. Currently the only thing I have in the View's code behind is creating the VM and adding it as the DataContext. I would like to use Unity for this and for getting Data Providers in the ViewModel. The MainWindow lays out a set of Views (each their own View+ViewModel). I do not want to construct the MainWindow's elements programatically so how to I get each View+ViewModel in the MainWindow to share the Unity Container - am I missing something fundamental about the MVVM or Unity Patters? – IUnknown Mar 01 '11 at 20:36
  • @IUnknown, updated answer with some sample. The idea is that `MainWindow` should be also designed in `MVVM` style – Snowbear Mar 01 '11 at 20:46
  • In the Shell.XAML (main window) you are binding the VM to the Content - I thought I would bind the View to the Content element. I do not see how I am bringing in the View. What am I missing? – IUnknown Mar 01 '11 at 21:56
  • @IUnknown, the idea is to bind a ViewModel there. View is usually brought there by datatemplating. It means that somewhere (`app.xaml` for example) you will have: `` for each view-viewmodel association. – Snowbear Mar 01 '11 at 22:01
  • Thank you - This nicely completes the Unity + MVVM picture for me. I was struggling with how some of the pieces came together but now it works and better yet makes sense. The only remaining question I have is where does `AutoMapperConfiguration` come from? That line is not in my solution but still works. Again thanks. – IUnknown Mar 02 '11 at 13:44
  • @IUnknown, oops that is part of our code, I will remove it. It is configuration for `AutoMapper` library, do you have it referenced? – Snowbear Mar 02 '11 at 14:07
  • You have just massively coupled your main view model with the child view models. As I understand the whole concept of DI, this design seems to be a giant step backwards. – Quark Soup Aug 09 '13 at 17:05