2015-05-06 82 views
0

我總是在一個項目中開發MVVM中的應用程序,並將Model,View,ViewModel和文件夾分開。看到不同的問題和不同的書籍,我瞭解到,在不同的項目中將它們分開會更好,因爲不同的原因,所以我試圖開發一個簡單的項目來看看它是如何工作的。WPF - MVVM多個項目結構

首先,我創建了一個包含不同文件夾的單個項目,然後啓動該應用程序並運行良好。 這是如何構建「單個項目」我省略了Model文件夾。

enter image description here

後,我創建了這3個項目組成的多個項目:

-MVVM

-MVVM.Views

-MVVM.ViewModels

該如何構成的 「多項目」

enter image description here

我設置MVVM.Views,MVVM.ViewModels輸出類型,DLL和不.EXE,我加入了項目(MVVM.Views,MVVM .ViewModels)在MVVM中的引用。

但是,當我吃午飯的應用程序,我得到一個錯誤

類型的未處理的異常「System.Exception的」發生在 WindowsBase.dll中信息:無法找到的 合同MVVM.ViewModels任何實例。 IShell的。

我也使用Caliburn.Micro 2.0.2爲bootstrapp,這是MefBootstrapper:

public class MefBootstrapper : BootstrapperBase 
{ 
    private CompositionContainer container; 

    public MefBootstrapper() 
    { 
     Initialize(); 
    } 

    protected override void Configure() 
    { 
     var catalog = new AggregateCatalog(
       AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>() 
       ); 

     container = new CompositionContainer(catalog); 

     var batch = new CompositionBatch(); 

     batch.AddExportedValue<IWindowManager>(new WindowManager()); 
     batch.AddExportedValue<IEventAggregator>(new EventAggregator()); 
     batch.AddExportedValue(container); 

     container.Compose(batch); 


     } 

     protected override object GetInstance(Type serviceType, string key) 
     { 
      string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(serviceType) : key; 
      var exports = container.GetExportedValues<object>(contract); 

      if (exports.Count() > 0) 
       return exports.First(); 

      throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract)); 
     } 

     protected override IEnumerable<object> GetAllInstances(Type serviceType) 
     { 
      return container.GetExportedValues<object>(AttributedModelServices.GetContractName(serviceType)); 
     } 

     protected override void BuildUp(object instance) 
     { 
      container.SatisfyImportsOnce(instance); 
     } 

     protected override void OnStartup(object sender, StartupEventArgs e) 
     { 
      DisplayRootViewFor<IShell>(); 
     } 
    } 

這是視圖模型代碼

namespace MVVM.ViewModels 
{ 
    public interface IShell { } 

    [Export(typeof(IShell))] 
    public class MainViewModel : PropertyChangedBase, IShell 
    { 

    } 
} 

我想了解我錯在哪裏?我錯過了一步?感謝您的支持

+0

請提供ViewModel代碼。另外,在獨立項目中使用ViewModel是有爭議的做法。包括我自己在內的許多WPF MVVM開發人員都將VM視爲與View綁定在一起的組件,並將它保持聯繫(甚至有一個插件可將ViewModel保留在XAML之後,旁邊是代碼隱藏)。但是,嘿,一般來說,無論如何你都會使用額外的控制器去使用MVCVM,然後控制器會去分離項目。 – mwilczynski

+0

我添加了代碼。我總是使用單個項目,因爲它更容易和快速,但閱讀我明白,最好將視圖從視圖模型和模型中分離出來,我只想學習這種類型,但我不確定將來我會使用這種方式。 – puti26

+0

分開項目是一種好的做法。我只是說ViewModels屬於'View'項目。模型,DAL等應該是所有獨立的項目。 – mwilczynski

回答

2

我發佈的答案,以防萬一有人會有我的同樣的問題。閱讀了很多帖子和不同的東西后,我發現這個錯誤。我忘了將程序集加載到應用程序中。這真的很簡單,只需在這裏更改Configure() void代碼:

protected override void Configure() 
{ 
    string pluginPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ""); 
    if (!Directory.Exists(pluginPath)) 
     Directory.CreateDirectory(pluginPath); 

    var fi = new DirectoryInfo(pluginPath).GetFiles("*.dll"); 
    AssemblySource.Instance.AddRange(fi.Select(fileInfo => Assembly.LoadFrom(fileInfo.FullName))); 

    var catalog = new AggregateCatalog(
      AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>() 
      ); 

    container = new CompositionContainer(catalog); 

    var batch = new CompositionBatch(); 

    batch.AddExportedValue<IWindowManager>(new WindowManager()); 
    batch.AddExportedValue<IEventAggregator>(new EventAggregator()); 
    batch.AddExportedValue(container); 

    container.Compose(batch); 
} 
+0

非常感謝。 – cryodream