WPF - MVVM 多项目结构
WPF - MVVM multiple projects structure
我总是在一个项目中使用 MVVM 开发应用程序,并将模型、视图、视图模型与文件夹分开。查看不同的问题和不同的书籍,我了解到出于不同的原因,将它们分开在不同的项目中会更好,因此我尝试开发一个简单的项目以查看其工作原理。
首先,我创建了一个包含不同文件夹的项目,然后我启动了该应用程序,它运行良好。
这是如何构建的 "single project" 我省略了 Model 文件夹。
在我创建了由这 3 个项目组成的多个项目之后:
-MVVM
-MVVM.Views
-MVVM.ViewModels
这是我构建 "multiple project"
的方式
我将 MVVM.Views、MVVM.ViewModels 输出类型设置为 Dll 而不是 .exe,我在 MVVM 中添加了项目(MVVM.Views、MVVM.ViewModels)引用。
但是当我午餐应用程序时出现错误
An unhandled exception of type 'System.Exception' occurred in
WindowsBase.dll Informations: Could not locate any instances of
contract MVVM.ViewModels.IShell.
我也在使用 Caliburn.Micro 2.0.2 作为引导程序,这是 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
{
}
}
我想知道我哪里错了?我错过了一步?感谢支持
我post回答以防万一有人遇到我同样的问题。在阅读了很多 posts 和不同的东西后,我发现了错误。我忘了将程序集加载到应用程序中。这真的很简单,只需更改代码中的 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);
}
我总是在一个项目中使用 MVVM 开发应用程序,并将模型、视图、视图模型与文件夹分开。查看不同的问题和不同的书籍,我了解到出于不同的原因,将它们分开在不同的项目中会更好,因此我尝试开发一个简单的项目以查看其工作原理。
首先,我创建了一个包含不同文件夹的项目,然后我启动了该应用程序,它运行良好。 这是如何构建的 "single project" 我省略了 Model 文件夹。
在我创建了由这 3 个项目组成的多个项目之后:
-MVVM
-MVVM.Views
-MVVM.ViewModels
这是我构建 "multiple project"
的方式我将 MVVM.Views、MVVM.ViewModels 输出类型设置为 Dll 而不是 .exe,我在 MVVM 中添加了项目(MVVM.Views、MVVM.ViewModels)引用。
但是当我午餐应用程序时出现错误
An unhandled exception of type 'System.Exception' occurred in WindowsBase.dll Informations: Could not locate any instances of contract MVVM.ViewModels.IShell.
我也在使用 Caliburn.Micro 2.0.2 作为引导程序,这是 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
{
}
}
我想知道我哪里错了?我错过了一步?感谢支持
我post回答以防万一有人遇到我同样的问题。在阅读了很多 posts 和不同的东西后,我发现了错误。我忘了将程序集加载到应用程序中。这真的很简单,只需更改代码中的 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);
}