将MVVM WPF解决方案与Caliburn Micro和MEF集成到一个旧的WPF应用程序中,其中包含代码隐藏和页面导航

时间:2013-01-31 04:41:07

标签: wpf caliburn.micro

去年我使用页面导航而不是MVVM构建了一个WPF应用程序。 最近我被要求为同一客户构建一个新的应用程序,我在使用Caliburn Micro和MEF的WPF MVVM中做了这个应用程序。现在,我的客户要求我将新应用程序集成到旧应用程序中。

我的想法是向旧应用程序添加一个新页面,并将新应用程序的shell集成到此页面的ContentControl中。

我现在的问题是旧应用程序是由

启动的

<StartupUri="Views\NavWindow.xaml">

在app.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放在哪里?

感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

CM很轻,在这些情况下,实际上值得查看源代码,看看特定类实际上在做什么。

Bootstrapper有效,因为在应用程序的资源文件中声明它会强制实例化它。构造函数在实例上调用Start并设置聚合器,IOC等。

https://caliburnmicro.codeplex.com/SourceControl/changeset/view/4de6f2a26b21#src/Caliburn.Micro.Silverlight/Bootstrapper.cs

如果你要将应用程序加载到另一个应用程序中的ContentControl,我就看不出它为什么不启动CM的原因,因为加载的应用程序的资源仍然会被处理,实例化和启动Bootstrapper等。您是否在测试项目中尝试过?这可能是你的第一选择。

可能有些地方CM的默认实现Bootstrapper可能不理想,但乍看之下我看不到任何明显的问题(不确定应用程序事件会发生什么,例如{{1}当你加载一个子应用程序,所以你可能想看看那个)。最糟糕的情况是,您可以为子应用推送自己的OnStartup,并使用经过调整的功能进行重建。