如何 code/design Caliburn.Micro 中的模型部分?

How to code/design the Model part in Caliburn.Micro?

我是 MVVM 模式的新手 Caliburn.Micro。我已经阅读了一些关于如何入门的教程,但我对 Caliburn 上下文中 MVVM 的 Model 部分感到困惑。

我想创建我的第一个 MVVM 应用程序,但我有一些设计问题:

在此先感谢您的帮助:)

编辑:---------------------------------------- ------------

谢谢你的回答。题目理解的比较清楚了,但是有些细节还是有点糊涂

举个例子,让我们假设这个小应用程序。我有一个允许我添加新客户的表格。它有几个字段,如姓名、姓氏等。 按下按钮后,我在 ViewModel 中调用 addCustomer 命令。我希望我的程序将新创建的客户存储在数据库中。

我的视图还有 List 控件(随便什么),它将我的客户显示为原始字符串(例如 "Name: John, Surname: Doe, Address: ..." 我知道这样做很愚蠢,但我需要一个模型操作示例(例如.toString()))

对于这个例子,我创建了一堆东西来说明我对该过程的看法:

我考虑了 2 种适合解决方案的方法:

哪个比较好?或者另一种更适合 MVVM 的方法?

另一个问题是:我应该把从数据库加载所有客户的方法放在哪里,以便他们可以显示在列表中?在 "get method" 视图模型内部,或模型内部 class?

In tutorials, the Model was presented as simple property in ViewModel. How should I manage more complex models? Is there any naming convention? Obviously, there should be some external classes made for my models, but how should I communicate between my models and the view?

您的模型应该代表他们需要的任何东西,无论是客户、帐户等。视图模型的工作是处理视图和模型之间的交互。

How should I keep references to many instances of one complex model? For ex. cumtomers (instances of Customer model class)

一般来说,您会将复杂的模型映射到更友好的显示格式,您可以手动完成,也可以使用AutoMapper 之类的工具。

Is there a possibility to manipulate one model class in many ViewModels? How should I store my model reference, so it'll be visible from different ViewModels?

如果您使用的是本地数据库,则可以传递 ID。如果它是一项服务,您可以在本地保留模型以供其他视图模型使用。您还可以将单例 ISharedData 注入到需要使用共享数据的视图模型中。

Where should I put my code for more complex model manupulation/file, database storage? How should I invoke such code? I'm not asking here about SQLConnections, but MVVM best practices. :)

为更复杂的模型操作/业务逻辑创建服务。将服务注入到需要它们的视图模型中。 ICustomerService、IAccountService 等

编辑:---------------------------------------- ------------

你第一种方法是正确的。关于共享模型的观点是一个严重的问题,因为保存方法绑定到视图模型 class。由于绑定,视图模型将有一个 SaveCustomerCommand,当单击按钮时会触发它。

SaveCustomerCommand 将保留 CustomerModel,无论 CustomerModel 是如何保留的。因此,如果它是一个数据库,则视图模型可能具有对上下文的引用并发出 _db.Save(CustomerModel)。如果另一个视图模型需要操作 CustomerModel,它将通过使用上下文来实现。视图模型还可以引用 CustomerService 来处理 CustomerModel.

的 crud

这可能是这样的:

public class AddCustomerViewModel : Screen
{
    private readonly ICustomerService _customerService;

    public AddCustomerViewModel(ICustomerService customerService)
    {
        _customerService = customerService;
    }

    //If button is named x:Name="SaveCustomer" CM will 
    //bind it by convention to this method
    public void SaveCustomer(Customer customer)
    {
        _customerService.Save(customer);
    }
}

public class CustomerListViewModel : Screen
{
    private readonly ICustomerService _customerService;
    private List<CustomerDisplayModel> _customers;

    public CustomerListViewModel(ICustomerService customerService)
    {
        _customerService = customerService;
    }

    public List<CustomerDisplayModel> Customers
    {
        get { return _customers; }
        set
        {
            _customers = value;
            NotifyOfPropertyChange();
        }
    }

    //only fires once, unlike OnActivate()
    protected override void OnInitialize()
    {
        var customers = _customerService.LoadAllCustomers();

        //could just use the model but this shows how one might map from
        //the domain model to a display model, AutoMapper could be used for this
        Customers = customers.Select(c => new CustomerDisplayModel(c)).ToList();
    }
}

public interface ICustomerService
{
    List<Customer> LoadAllCustomers();
    void Save(Customer customer);
}

//same as button, Label named x:Name="CustomerName" will bind
// to CustomerName
public class CustomerDisplayModel
{
    private readonly Customer _customer;

    public CustomerDisplayModel(Customer customer)
    {
        _customer = customer;
    }

    public string CustomerName
    {
        get { return _customer.Name; }
        set { _customer.Name = value; }
    }

    public string Surname
    {
        get { return _customer.Surname; }
        set { _customer.Surname = value; }
    }

    public string Address
    {
        get { return _customer.Address; }
        set { _customer.Address = value; }
    }
}

public class Customer
{
    public int Id { get; set; }

    public string Name { get; set; }

    public string Surname { get; set; }

    public string Address { get; set; }
}