Windows 8 MEF

Nov 13, 2012 at 6:18 AM
Edited Nov 13, 2012 at 7:10 AM

Okay, I've looked all over and can't find anything in the samples.  Only thing I've been able to find regarding usage in Windows 8 is the blog posts about it being released on Nuget.  I've copied this code to my App.xaml.cs

var configuration = new ContainerConfiguration().WithAssembly(typeof(App).GetTypeInfo().Assembly);

I've confirmed that when my application starts that I can get instances of the exported classes while stepping through the debugger using 

_mefContainer = configuration.CreateContainer();
var viewModel = _mefContainer.GetExport<MainViewModel>();

 

However, when the default code in OnLaunched runs and I'm assuming this is where it is not using my instance of MainView because I'm not using GetExport for it.

if (!rootFrame.Navigate(typeof(MainView), args.Arguments))

It is not using an instance of the view from the container.  Here is the my view constructor with export and import attributes for the view model.

    [Export]
    public sealed partial class MainView : Page
    {
        public MainView()
        {
            this.InitializeComponent();
        }

        [Import]
        public MainViewModel ViewModel 
        { 
            get
            {
                return _viewModel;
            }
            set
            {
                _viewModel = value;
                this.DataContext = value;
            }
        }
        private MainViewModel _viewModel;

Any ideas on what I'm doing wrong?  I've used MEF with Prism in an WPF appliaction before and had no problems with it so I'm familiar with how to set up the classes to correctly import and export objects.  I'm just stumped on how to correctly setup and use the container other than using GetExport<T> everytime - Is that how I'm supposed to do it?  Would be great to find a simple Win8 app sample that used MEF.

Update:

I've removed [Export] from my view and instead changed to get the DataContext as follows:

public MainView()
        {
            this.InitializeComponent();
            this.DataContext = App.MefContainer.GetExport(typeof(MainViewModel));
        }   
This works and my MainViewModel is used from the container.  Is this the expected way to use this?  Is there anyway to use the container instance of MainView and use Frame.Navigate to get to it?  Or is there another navigation method in Windows 8 apps that could be used?

Nov 14, 2012 at 4:51 PM
Edited Nov 14, 2012 at 4:56 PM

You need to do the GetExport on your View since that's what you're exporting. 

 

 

var mainView = _mefContainer.GetExport<MainView>();

...

if (!rootFrame.Navigate(typeof(mainView), args.Arguments))

 

I've got a sample project with MEF and trying to hook it up with Caliburn.Micro. You can see how MEF gets set up at least.

http://caliburnmicro.codeplex.com/discussions/399671

Nov 14, 2012 at 6:27 PM

@iamdragonwolf: the Navigate code will not compile because "mainView" is not a type. 

Nov 14, 2012 at 11:38 PM
Edited Nov 15, 2012 at 4:57 PM

Oh right, an instance doesn't work since the NavigationService wants to create the instance itself.

You could have the Frame created in your MainView and navigate from there if you need the navigation and then you can use

var mainView = _mefContainer.GetExport<MainView>();
Window.Current.Content = mainView;
Window.Current.Activate();

You're still stuck with pages not being pulled from a container, however, for navigation after MainView is loaded. I think with the default navigation being view-first, you'll have to create your own navigation to use with MEF or move to a viewmodel first approach.

Caliburn.Micro fits in nicely if you're going that route. You'll have to pull the latest source as there hasn't been a release of the Win8 changes yet.