去年我使用页面导航而不是MVVM构建了一个WPF应用程序。 最近我被要求为同一客户构建一个新的应用程序,我在使用Caliburn Micro和MEF的WPF MVVM中做了这个应用程序。现在,我的客户要求我将新应用程序集成到旧应用程序中。
我的想法是向旧应用程序添加一个新页面,并将新应用程序的shell集成到此页面的ContentControl
中。
我现在的问题是旧应用程序是由
启动的 <StartupUri="Views\NavWindow.xaml">
,而新应用程序由像
这样的引导程序启动 <local:AppBootstrapper x:Key="bootstrapper" />
AppBootstrapper看起来像
class AppBootstrapper : Bootstrapper<ShellViewModel>
{
private CompositionContainer container;
protected override void Configure()
{
container = new CompositionContainer(new AggregateCatalog(AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()));
CompositionBatch 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));
}
}
因此,据我了解,如果是新应用,引导程序会初始化整个应用,请调用ShellViewModel
,最后调用ShellView
。
因为我使用新应用程序中的EventAggregator
将消息从一个视图模型发送到另一个视图模型,我认为我无法摆脱引导程序并使用Caliburn Micro的视图优先模型。
所以我的问题是:我可以自己从我的旧应用程序调用引导程序,如果是这样,我应该在哪里存储它的实例,以及如何告诉Caliburn Micro将ShellView
放在哪里?
感谢任何帮助。
答案 0 :(得分:0)
CM很轻,在这些情况下,实际上值得查看源代码,看看特定类实际上在做什么。
Bootstrapper
有效,因为在应用程序的资源文件中声明它会强制实例化它。构造函数在实例上调用Start
并设置聚合器,IOC等。
如果你要将应用程序加载到另一个应用程序中的ContentControl
,我就看不出它为什么不启动CM的原因,因为加载的应用程序的资源仍然会被处理,实例化和启动Bootstrapper
等。您是否在测试项目中尝试过?这可能是你的第一选择。
可能有些地方CM的默认实现Bootstrapper
可能不理想,但乍看之下我看不到任何明显的问题(不确定应用程序事件会发生什么,例如{{1}当你加载一个子应用程序,所以你可能想看看那个)。最糟糕的情况是,您可以为子应用推送自己的OnStartup
,并使用经过调整的功能进行重建。