2015-10-09 63 views
2

我使用WPF Prism創建了一個小型演示應用程序,並且使用了Mef。使用MEF在Prism中查看初始化時出現問題

這裏是應用程序的外殼:

<Window ..........> 
    <Grid> 
     <ContentControl 
      prism:RegionManager.RegionName="{x:Static inf:RegionNames.ContentRegion}" /> 
    </Grid> 
</Window> 

這裏ContentRegion只是在另一個類基礎設施項目的定義的靜態字符串。

這裏是我的引導程序類:

public class Bootstrapper : MefBootstrapper 
{ 
    protected override DependencyObject CreateShell() 
    { 
     return Container.GetExportedValue<Shell>(); 
    } 

    protected override void InitializeShell() 
    { 
     base.InitializeShell(); 

     App.Current.MainWindow = (Window)Shell; 
     App.Current.MainWindow.Show(); 
    } 

    protected override void ConfigureAggregateCatalog() 
    { 
     AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Bootstrapper).Assembly)); 
     AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(RegionNames).Assembly)); 
     AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleMyModule).Assembly)); 
    } 
} 

正如你可以看到我已經加入我的主要執行項目及其基礎設施項目,這個引導程序。

現在我創建了一個名爲MyModule的非常簡單的模塊。 它有一個類調用ModuleMyModule:

[ModuleExport(typeof(ModuleMyModule), InitializationMode = InitializationMode.WhenAvailable)] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
public class ModuleMyModule : IModule 
{ 
    IRegionManager _regionManager; 

    [ImportingConstructor] 
    public ModuleMyModule(IRegionManager regionManager) 
    { 
     _regionManager = regionManager; 
    } 

    public void Initialize() 
    { 
     _regionManager.RegisterViewWithRegion(RegionNames.ContentRegion, typeof(MyView)); 
    } 
} 

現在,我有一個名爲MyView的這個應用程序,如下查看:

<UserControl ............> 
    <Grid> 
     <CheckBox Content="Have you Checked it properly?"/> 
    </Grid> 
</UserControl> 

高達此時我的應用程序工作正常。

現在的問題開始:

現在,我添加了一個視圖模型到這個項目中。所以,現在我的觀點MyView的樣子:

<UserControl ............> 
    <Grid> 
     <CheckBox IsChecked="{Binding IsProperlyChecked}" Content="Have you Checked it properly?"/> 
    </Grid> 
</UserControl> 

,這裏是MyView的的cs文件:

[Export(typeof(MyView))] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
public partial class MyView : UserControl, IView 
{ 
    [ImportingConstructor] 
    public MyView(IMyViewModel viewModel) 
    { 
     InitializeComponent(); 
     ViewModel = viewModel; 
    } 

    public IViewModel ViewModel 
    { 
     get 
     { 
      return (IViewModel)DataContext; 
     } 
     set 
     { 
      DataContext = value; 
     } 
    } 
} 

這裏是我的ViewModel類:

[Export(typeof(MyViewModel))] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
public class MyViewModel : IMyViewModel, INotifyPropertyChanged 
{ 
    [ImportingConstructor] 
    public MyViewModel() 
    { 
     IsProperlyChecked = true; 
    } 

    private bool _IsProperlyChecked; 

    public bool IsProperlyChecked 
    { 
     get 
     { 
      return _IsProperlyChecked; 
     } 
     set 
     { 
      if (_IsProperlyChecked != value) 
      { 
       _IsProperlyChecked = value; 
       OnPropertyChanged("IsProperlyChecked"); 
      } 
     } 
    } 

    public void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

IMyViewModel是一個接口如下圖所示:

public interface IMyViewModel : IViewModel 
{ 
    bool IsProperlyChecked { get; set; } 
} 

現在,我的項目停止工作:

我得到一個錯誤:

An exception has occurred while trying to add a view to region 'ContentRegion'. 

    - The most likely causing exception was was: 'Microsoft.Practices.ServiceLocation.ActivationException: Activation error occured while trying to get instance of type MyView, key "" ---> Microsoft.Practices.ServiceLocation.ActivationException: Activation error occured while trying to get instance of type MyView, key "" 

    at Microsoft.Practices.Prism.MefExtensions.MefServiceLocatorAdapter.DoGetInstance(Type serviceType, String key) 

    at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) 

    --- End of inner exception stack trace --- 

    at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) 

    at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType) 

    at Microsoft.Practices.Prism.Regions.RegionViewRegistry.CreateInstance(Type type) 

    at Microsoft.Practices.Prism.Regions.RegionViewRegistry.<>c__DisplayClass1.<RegisterViewWithRegion>b__0() 

    at Microsoft.Practices.Prism.Regions.Behaviors.AutoPopulateRegionBehavior.OnViewRegistered(Object sender, ViewRegisteredEventArgs e)'. 

爲什麼這個異常被拋出?

我覺得我做錯了什麼。我對MEF非常陌生,以前我用過Unity。

那裏我需要註冊ViewModel及其界面。但我不知道在MEF中是否需要它。如果需要,那麼如何?

演示項目:

https://drive.google.com/file/d/0Bw2XAE1EBI6rU3VsYjVyQmhFRFE/view?usp=sharing

回答

4

當使用MEF作爲ExportAttribute參數應匹配通過進口(多個)期望的類型傳遞的類型。

由於MyView構造函數需要IMyViewModel類型:

[ImportingConstructor] 
public MyView(IMyViewModel viewModel) 
{ 
.. 

...嘗試出口MyViewModel類爲IMyViewModel

[Export(typeof(IMyViewModel))] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
public class MyViewModel : IMyViewModel, INotifyPropertyChanged 
{ 
    ... 
+0

哦!那很簡單。我自己弄不明白。但現在我會牢記在心。感謝您的幫助。 – Khushi