【发布时间】:2015-05-06 13:14:42
【问题描述】:
我总是在一个项目中使用 MVVM 开发应用程序,并将 Model、View、ViewModel 与文件夹分开。通过查看不同的问题和不同的书籍,我了解到,出于不同的原因,将它们分开放在不同的项目中会更好,因此我尝试开发一个简单的项目来看看它是如何工作的。
首先,我创建了一个包含不同文件夹的项目,然后我启动了应用程序,它运行良好。 这是我省略了模型文件夹的“单个项目”的结构。
在我创建了由这 3 个项目组成的多个项目之后:
-MVVM
-MVVM.Views
-MVVM.ViewModels
这就是我构建“多个项目”的方式
我将 MVVM.Views,MVVM.ViewModels 输出类型设置为 Dll 而不是 .exe,我在 MVVM 中添加了项目(MVVM.Views,MVVM.ViewModels) 引用。
但是当我午餐应用程序时,我得到一个错误
“System.Exception”类型的未处理异常发生在 WindowsBase.dll 信息:找不到任何实例 合约 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
{
}
}
我想了解我错在哪里?我错过了一步?感谢支持
【问题讨论】:
-
请提供 ViewModel 代码。此外,在单独的项目中使用 ViewModel 也是有争议的做法。包括我自己在内的许多 WPF MVVM 开发人员都将 VM 视为与 View 相关联的组件并使其保持耦合(甚至还有一个插件可以将 ViewModel 保持在 XAML 之后,在代码隐藏旁边)。但是,嘿,一般来说,无论如何你都会使用带有额外控制器的 MVCVM,然后控制器会转到单独的项目。
-
我添加了代码。我总是使用单个项目,因为它更容易和快速,但是阅读我理解最好将视图与视图模型和模型分开,我也想学习这种但我不确定将来我会用这种方式。
-
分离到项目中是一种很好的做法。我只是说 ViewModels 属于“视图”项目。模型、DAL 等应该都是独立的项目。
-
所以你说我应该在 MVVM.Views 项目中使用 ViewModels 文件夹?
-
我不知道关于 CM 的工作表,但我知道在运行时使用反射来加载类型。如果您的应用程序中有两个程序集,A.EXE 和 B.DLL,并且您想在 A.EXE 中加载 B.DLL 中定义的类型,则必须将 B.DLL 加载到 AppDomain 中才能访问那些类型。 CM 可能正在寻找实现 IShell 的 appdomain 中的类型,但是 MVVM.ViewModels 不会加载到可执行文件的 appdomain 中,并且 CM 不会加载随机程序集来寻找它。解决方案?有很多,不确定哪个最适合您。
标签: c# wpf mvvm caliburn.micro