Caliburn Micro MVVM 多活动项和 IoC 依赖注入

问题描述

我偶然发现了一个问题,我在 CM 的官方文档中没有找到解决方案。 我们的应用程序看起来与此图像相似:

Structure

搜索 StackOverflow 时,我找到了使用 Conductor<object>.Collection.AllActive 类 (more active screens / views in shell caliburn micro or another MVVM framework) 执行类似操作的解决方案。我遇到的最大问题是,我找不到使用工厂进行依赖注入的方法Shellviewmodel 的构造函数目前看起来像这样。

public Shellviewmodel(
            Func<Footerviewmodel> footerviewmodelFactory,Func<Loginviewmodel> loginviewmodelFactory)
{
   this.ActivateItemAsync(loginviewmodelFactory);
   this.ActivateItemAsync(footerviewmodelFactory);
}

显然这是行不通的,因为ContentControl不能显示工厂,需要一个Screen。但是我如何首先设法将对象绑定到外壳,同时仍然保持依赖注入的特性?否则,一个简单的解决方法就是为 viewmodel 创建一个新实例并传递所有参数,这在我看来简直太脏了。

解决方法

我终于明白了。虽然我讨厌 Java 中的工厂模式,但它在 Caliburn Micro 中似乎是必要的并且是有道理的。

无论如何,我创建了一个类似这样的工厂:

public class FooterFactory
{
    // Add all the needed interfaces you get injected from the IoC container here.
    private readonly IMyInterface myImplementation;

    public FooterFactory(IMyInterface myImplementation,...)
    {
        this.myImplementation = myImplementation;
    }

    //Creates the ViewModel. You can also pass some parameters here.
    public FooterViewModel Create(...)
    {
        return new FooterViewModel (...,this.myImplementation);
    }
}

在工厂被添加到引导程序后,它可以很容易地添加,如下所示。不过,我的最初方法有一些问题。因此,我稍微更改了代码。

public ShellViewModel(
            FooterFactory footerFactory,Func<LoginViewModel> loginViewModelFactory)
{
   this.ActivateItemAsync(loginViewModelFactory);
   this.FooterViewModel = footerFactory.Create(...);
}

我的 XAML 看起来像这样。

<Window x:Class="My.Client.ShellView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        WindowState="Maximized"
        WindowStartupLocation="CenterScreen"
        Title="Dummy" Icon="/Resources/favicon.ico">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="120" />
        </Grid.RowDefinitions>

        <ContentControl Name="ActiveItem" Grid.Row="0"/>
        <ContentControl Name="FooterViewModel" Grid.Row="1" />
    </Grid>
</Window>

注意:正如我所说,这是我使用的代码的简化版本。无论如何,它应该强调如何解决这个问题的方法。这种方法的好处是,您不需要带有多个项目控件的 Conductor<>.Collection。因此,您无需弄乱对象的顺序,例如,如果一个对象的加载时间比另一个对象长,或者您必须停用某些对象。 + 如果您想在屏幕上显示更多内容(例如标题、菜单栏等),您可以在 XAML 中创建多个 ContentControl

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...