MvvmCross TipCalc - 步骤 1:创建核心可移植应用程序
MvvmCross v3 - Hot Tuna 的 TipCalc 教程的步骤 1。
介绍
本文是 MvvmCross v3 - Hot Tuna! 的 TipCalc
教程的第一步。
开始可移植开发
MvvmCross 应用程序通常的结构是:
- 一个共享的“核心”可移植类库 (PCL) 项目
- 包含尽可能多的代码:模型、视图模型、服务、转换器等。
- 每个平台一个 UI 项目
- 每个项目包含该平台的引导程序和特定于视图的代码。
通常,您从核心项目开始开发——这正是我们在这里要做的事情。
要创建核心,您可以使用 Visual Studio 项目模板向导,但在这里我们将从“空项目”开始构建一个新项目。
创建可移植类库
使用 Visual Studio,通过“文件 | 新建项目”向导创建您的新 PCL。
将其命名为 TipCalc.Core.csproj 之类的名称。
当被要求选择平台时,请选择所有 WindowsPhone、WindowsStore (.NET 4.5)、Xamarin.Android 和 Xamarin.iOS——这将确保 PCL 位于 Profile104。此配置文件定义了一小部分 .NET,其中包含以下程序集的组成部分:
mscorlib
System.Core
System.Net
System.Runtime.Serialization
System.ServiceModel
System.Windows
System.Xml
System.Xml.Linq
System.Xml.Serialization
对我们来说重要的是,Profile104 包含了构建 Mvvm 应用程序所需的一切。
删除 Class1.cs
没有人真正需要 Class1
。 " align="top" src="https://codeproject.org.cn/script/Forums/Images/smiley_smile.gif" />
添加对 CrossCore 和 MvvmCross 程序集的引用
使用“添加引用”来链接这两个可移植类库。
- Cirrious.CrossCore.dll
- 核心接口和概念,包括跟踪、IoC 和插件管理
- Cirrious.MvvmCross.dll
- Mvvm 类 - 包括
MvxApplication
和MvxViewModels
的基类。
- Mvvm 类 - 包括
通常,这些文件会位于类似 {SolutionRoot}/Libs/Mvx/Portable/ 的文件夹路径中。
添加小费计算服务
创建一个名为“Services”的文件夹。
在此文件夹中,创建一个新的接口,用于计算小费。
public interface ICalculation
{
double TipAmount(double subTotal, int generosity);
}
在此文件夹中,创建此接口的实现。
public class Calculation : ICalculation
{
public double TipAmount(double subTotal, int generosity)
{
return subTotal * ((double)generosity)/100.0;
}
}
这为我们的应用程序提供了一些简单的业务逻辑。
添加 ViewModel
从草图层面来看,我们希望有一个用户界面,它:
- 使用
- 我们的计算服务来计算小费。
- 有以下输入:
- 当前账单(subTotal)
- 对我们想留下多少小费的感知(generosity)。
- 有以下输出显示:
- 要留下的小费金额。
为了表示这个用户界面,我们需要为用户界面构建一个“模型”——当然,这就是“ViewModel
”。
在 MvvmCross 中,所有 ViewModel
都应继承自 MvxViewModel
。
所以现在,在我们的项目中创建一个 ViewModels 文件夹,并在该文件夹中添加一个名为 TipViewModel
的新类,如下所示:
using Cirrious.MvvmCross.ViewModels;
namespace TipCalc.Core
{
public class TipViewModel : MvxViewModel
{
private readonly ICalculation _calculation;
public TipViewModel(ICalculation calculation)
{
_calculation = calculation;
}
public override void Start()
{
_subTotal = 100;
_generosity = 10;
Recalcuate();
base.Start();
}
private double _subTotal;
public double SubTotal
{
get { return _subTotal; }
set { _subTotal = value; RaisePropertyChanged(() => SubTotal); Recalcuate(); }
}
private int _generosity;
public int Generosity
{
get { return _generosity; }
set { _generosity = value; RaisePropertyChanged(() => Generosity); Recalcuate(); }
}
private double _tip;
public double Tip
{
get { return _tip; }
set { _tip = value; RaisePropertyChanged(() => Tip);}
}
private void Recalcuate()
{
Tip = _calculation.TipAmount(SubTotal, Generosity);
}
}
}
对你们中的许多人来说,这个 TipViewModel
已经很清楚了。如果不是,那么请跳到“创建应用程序”。如果不是,那么这里有一些简单的解释:
-
TipViewModel
是通过一个ICalculation
服务构造的。private readonly ICalculation _calculation; public TipViewModel(ICalculation calculation) { _calculation = calculation; }
-
构造完成后,
TipViewModel
将被启动——在此过程中,它会设置一些初始值。public override void Start() { // set some start values SubTotal = 100.0; Generosity = 10; Recalculate(); }
-
TipViewModel
中包含的视图数据通过属性公开。- 这些属性中的每一个都由一个
private
成员变量支持。 - 这些属性中的每一个都有
get
和set
。 - Tip 的
set
访问器被标记为private
。 - 所有
set
访问器都调用RaisePropertyChanged
来通知基类MvxViewModel
数据已更改。 -
SubTotal
和Generosity set
访问器还调用Recalculate()
。private double _subTotal; public double SubTotal { get { return _subTotal; } set { _subTotal = value; RaisePropertyChanged(() => SubTotal); Recalculate(); } } private int _generosity; public int Generosity { get { return _generosity; } set { _generosity = value; RaisePropertyChanged(() => Generosity); Recalculate(); } } private double _tip; public double Tip { get { return _tip; } private set { _tip = value; RaisePropertyChanged(() => Tip); } }
- 这些属性中的每一个都由一个
-
Recalculate
方法使用_calculation
服务根据SubTotal
和Generosity
的当前值更新Tip
。private void Recalculate() { Tip = _calculation.TipAmount(SubTotal, Generosity); }
添加应用程序 (App)
在定义了 Calculation
服务和 TipViewModel
之后,我们现在只需要添加主要的 App 代码。
- 这段代码将位于我们 PCL 核心项目根文件夹中的单个类中。
- 这个类将继承自
MvxApplication
类。 - 这个类通常就叫 App。
- 这个类负责提供:
- 应用程序使用的接口和实现注册。
- 应用程序启动时显示的
ViewModel
注册。 ViewModel
定位的控制——尽管大多数应用程序通常只使用基类MvxApplication
提供的默认实现。
这里的“注册”意味着创建一个“控制反转”——IoC——记录,用于一个接口。这个 IoC 记录告诉 MvvmCross 框架当任何代码请求该接口的实例时应该做什么。
对于我们的 Tip Calculation App:
-
我们将
Calculation
类注册为实现ICalculation
服务。Mvx.RegisterType<ICalculation, Calculation>();
这一行告诉 MvvmCross 框架,当任何代码请求
ICalculation
引用时,框架应该创建一个新的Calculation
实例。 -
我们希望应用程序从
TipViewModel
开始。var appStart = new MvxAppStart<TipViewModel>(); Mvx.RegisterSingleton<IMvxAppStart>(appStart);
这一行告诉 MvvmCross 框架,当任何代码请求
IMvxAppStart
引用时,框架应该返回同一个appStart
实例。
所以 App.cs 看起来是这样的:
using Cirrious.CrossCore.IoC;
using Cirrious.MvvmCross.ViewModels;
namespace TipCalc.Core
{
public class App : MvxApplication
{
public App()
{
Mvx.RegisterType<ICalculation,Calculation>();
Mvx.RegisterSingleton<IMvxAppStart>(new MvxAppStart<TipViewModel>());
}
}
}
注意:什么是“控制反转”?
我们在这里不深入探讨 IoC——控制反转——是什么。
相反,我们只说:
- 在每个 MvvmCross 应用程序中,都有一个单一的特殊对象——单例。
- 这个单例存在于
Mvx static
类中。 - 应用程序启动代码可以使用
Mvx.Register
方法来指定在应用程序的生命周期内将实现哪些接口。 - 完成此操作后,在稍后的生命周期中,当任何代码需要接口实现时,它可以使用
Mvx.Resolve
方法来请求一个。
一种常见的模式是“构造函数注入”。
- 我们的
TipViewModel
使用了这种模式。 - 它呈现了一个构造函数,如下所示:
public TipViewModel(ICalculation calculation)
。 - 当应用程序运行时,MvvmCross 框架的一部分称为
ViewModelLocator
,用于查找和创建ViewModels
。 - 当需要
TipViewModel
时,ViewModelLocator
使用对Mvx.IocConstruct
的调用来创建一个。 - 这个
Mvx.IocConstruct
调用通过使用Mvx.Resolve
找到的ICalculation
实现来创建TipViewModel
。
这显然只是一个非常简短的介绍。
如果您想了解更多信息,请查看互联网上一些出色的教程——就像这篇教程一样。
核心项目已完成
" align="top" src="https://codeproject.org.cn/script/Forums/Images/smiley_smile.gif" />
我们来回顾一下我们遵循的步骤:
- 我们使用 Profile104 创建了一个新的 PCL 项目。
- 我们添加了对两个 PCL 库——
CrossCore
和MvvmCross
——的引用。 - 我们添加了一对
ICalculation
接口和实现。 - 我们添加了一个
TipViewModel
,它:- 继承自
MvxViewModel
。 - 使用了
ICalculation
。 - 公开了许多
public
属性,每个属性都调用了RaisePropertyChanged
。
- 继承自
- 我们添加了一个 App,它:
- 继承自
MvxApplication
。 - 注册了
ICalculation
/Calculation
对。 - 为
IMvxAppStart
注册了一个特殊的启动对象。
- 继承自
这些是您为每个新的 MvvmCross 应用程序需要遵循的相同步骤。
继续
接下来,我们将开始研究如何为这个 MvvmCross 应用程序添加第一个 UI。
文章
- MvvmCross TipCalc - 步骤 1:创建核心可移植应用程序
- MvvmCross TipCalc - 第 2 步:创建 Android UI
- MvvmCross TipCalc - 第 3 步:创建 iOS UI
- MvvmCross TipCalc - 第 4 步:创建 Windows Phone UI
- MvvmCross TipCalc - 第 5 步:创建 Windows Store UI
- MvvmCross TipCalc - 步骤 6:创建 WPF UI
- MvvmCross TipCalc - 回顾
历史
- 2013 年 3 月 22 日 - 首次提交