问题
I'm familiar with using MEF in .NET Framework 4.6.* but not in .NET Core. I'm messing about with the Hamburger template from Template 10 to see if it is suitable for my needs but I haven't been able to figure out how to compose my view models using MEF.
My question is how can I navigate to a view using the navigation service in such a way that its view model will be injected by MEF?
回答1:
I have one way of getting this working but it seems a bit code smelly so better answers are welcomed. I created a static class holding an instance of the CompositionHost
. It has a method for resolving imports. The view's code behind calls the static class to create its view model.
public static class Container
{
public static CompositionHost Host { get; set; }
public static T Get<T>()
{
T obj = Host.GetExport<T>();
Host.SatisfyImports(obj);
return obj;
}
}
In the App
class:
public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs args)
{
var config = new ContainerConfiguration();
Container.Host = config.WithAssembly(GetType().GetTypeInfo().Assembly).CreateContainer();
await NavigationService.NavigateAsync(typeof(Views.MainPage));
}
In the view's code behind:
public sealed partial class MainPage : Page
{
private MainPageViewModel ViewModel { get; }
public MainPage()
{
InitializeComponent();
NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
ViewModel = Container.Get<MainPageViewModel>();
DataContext = ViewModel;
}
}
回答2:
My bad, I hadn't spotted this:
How do I use a Unity IoC container with Template10?
In the end, I went for a solution like this:
public interface IView
{
ViewModelBase ViewModel { get; }
}
[Export]
public sealed partial class MainPage : Page, IView
{
public ViewModelBase ViewModel
{
get
{
return VM as ViewModelBase;
}
}
[Import]
public MainPageViewModel VM { get; set; }
public MainPage()
{
InitializeComponent();
NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
}
}
And in the App.xaml.cs:
public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs args)
{
var config = new ContainerConfiguration();
_container = config.WithAssembly(GetType().GetTypeInfo().Assembly).CreateContainer();
await NavigationService.NavigateAsync(typeof(Views.MainPage));
}
public override INavigable ResolveForPage(Page page, NavigationService navigationService)
{
_container.SatisfyImports(page);
return (page as IView)?.ViewModel;
}
来源:https://stackoverflow.com/questions/41745561/template-10-dependency-injection-using-mef