2015-05-06 5 views
0

Я всегда разрабатывал приложение в MVVM в одном проекте и отдельные папки Model, View, ViewModel wth. Глядя на разные вопросы и разные книги, я узнал, что их разделение в разных проектах будет лучше по разным причинам, поэтому я пытался разработать простой проект, чтобы увидеть, как он работает.WPF - структура нескольких проектов MVVM

Во-первых, я создал один проект с разными папками, и я запускаю приложение, и оно работает хорошо. Это как структурированный «единственный проект», я опустил папку «Модель».

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>(); 
     } 
    } 

Это ViewModel код:

namespace MVVM.ViewModels 
{ 
    public interface IShell { } 

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

    } 
} 

Я хочу понять, где я ошибаюсь? Я пропустил один шаг? Спасибо за поддержку

+0

Просьба предоставить код ViewModel. Кроме того, наличие ViewModel в отдельном проекте является спорной практикой. Многие разработчики WPF MVVM, включая меня, рассматривают VM как компонент, привязанный к View и поддерживающий его (есть даже плагин, чтобы держать ViewModel за XAML, рядом с кодом). Но эй, в общем, вы бы в любом случае пошли бы MVCVM с дополнительным контроллером, и Controller тогда пойдет в отдельный проект. – mwilczynski

+0

Я добавил код.Я всегда использовал один проект, потому что это проще и быстрее, но, читая, я понимаю, что лучше оставить отдельный вид из модели просмотра и из модели, я просто хочу изучить этот вид, но я не уверен, что в будущем буду используйте этот способ. – puti26

+0

Отличная работа в проектах. Я просто говорю, что ViewModels принадлежат проекту «Просмотр». Модель, DAL и т. Д. Должны быть все отдельными проектами. – mwilczynski

ответ

2

Я отправляю ответ на случай, если у кого-то будут мои проблемы. Прочитав много сообщений и разных вещей, я нашел ошибку. Я забыл загрузить сборки в приложение. И это действительно просто просто изменить Configure() аннулировать код:

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

Смежные вопросы