简单的快速入门 - 将 Unity Container 与 Silverlight 结合使用
一个简单的快速入门,用于在 Silverlight 中使用 Unity 容器。
引言
我们将使用构造函数注入来添加两个数字,然后在 Silverlight XAML 页面中显示它们的总和。为了使用构造函数注入,我们将使用 Unity 容器。
背景
在阅读本文之前,具备依赖注入的一些知识将是一个额外的优势。Silverlight 的 Unity Application Block 1.2 已在附加到本文的代码中使用。
Using the Code
要了解 Unity 在此示例中的工作方式,我们首先需要了解当我们添加两个数字并生成总数时,我们依赖于什么(有什么猜测吗?)。是的,总数实际上取决于正在相加的数字(我想这很明显!)。
要相加的两个数字在示例代码中表示为接口。对于这些数字,以这种方式在示例中实现更有意义,以便正确展示构造函数注入。
让我们首先看看如何在示例代码中表示一个数字。我们使用一个接口,然后在数字类中实现此接口。第二个数字也以类似的方式实现。
//Interface
public interface INumberA {
int NumA {get;set;}
}
//Number
public class NumberA:INumberA {
private int intNumA;
public int NumA
{
get {return intNumA;}
set { intNumA = value; }
}
}
接下来,我们转到 Total
类。此类有一个构造函数,它接受两个参数作为数字,并将每个参数分配给私有类变量。我们稍后会看到 NumA
和 NumB
是什么。
public Total(INumberA objA, INumberB objB)
{
this.objA = objA;
this.objB = objB;
NumA = 0;
NumB = 0;
}
Total
类还将实现 INotifyPropertyChanged
接口。由于我们将 NumA
、NumB
和 Sum
绑定到 XAML 中的文本框,因此这些属性必须引发更改事件(在此示例中通过 OnPropertyChanged
)。
public int Sum {
get {
return intSum;
}
set {
if (intSum != value) {
intSum = value;
OnPropertyChanged("Sum");
}
}
}
public int NumA {
get {
return objA.NumA;
}
set {
if (objA.NumA != value) {
objA.NumA = value;
OnPropertyChanged("NumA");
GetSum();
}
}
}
public int NumB {
get {
return objB.NumB;
}
set {
if (objB.NumB != value) {
objB.NumB = value;
OnPropertyChanged("NumB");
GetSum();
}
}
}
GetSum
方法是实际进行数字求和的地方。
private void GetSum()
{
Sum = objA.NumA + objB.NumB;
}
转到 XAML 文件(在本例中为 *Page.xaml*)。它在网格内对齐了一些文本框控件。这些文本框主要负责显示两个数字及其总和。在此示例中,我不会深入研究 XAML 布局。
<textbox x:name="num1" text="{Binding Mode=TwoWay, Path=NumA}"
maxlength="4" grid.column="0" grid.row="1"
fontweight="Normal" fontsize="14"
verticalalignment="Center" horizontalalignment="Center" />
<textbox text="+" maxlength="1" grid.column="1"
grid.row="1" fontweight="Normal" fontsize="14"
verticalalignment="Center" horizontalalignment="Center"
isreadonly="True" />
<textbox x:name="num2" text="{Binding Mode=TwoWay, Path=NumB}"
maxlength="4" grid.column="2" grid.row="1"
fontweight="Normal" fontsize="14"
verticalalignment="Center" horizontalalignment="Center" />
<button type="button" width="30" grid.column="3"
grid.row="1" verticalalignment="Bottom"
content="=" height="30">
<textbox x:name="txtBlock" text="{Binding Sum}"
maxlength="6" grid.column="4" grid.row="1"
fontweight="Normal" fontsize="14" verticalalignment="Center"
horizontalalignment="Center" isreadonly="True"/>
现在,最重要的是,如果我们查看 XAML 代码隐藏文件,我们会看到在页面加载时执行的方法中包含以下代码。
private void Page_Loaded(object sender, RoutedEventArgs e) {
IUnityContainer container = new UnityContainer();
//Interfaces used - so register the correct type
container.RegisterType<INumberA,NumberA>();
container.RegisterType<INumberB,NumberB>();
//Unity takes care of instantiation of all dependent classes
this.DataContext = container.Resolve<Total>();
}
我们创建 Unity 容器的一个实例。此实例将负责实例化它发现的、Total
类要实例化所需的所有依赖类。因此,当我们说 container.Resolve<Total>()
时,Total
类及其构造函数中定义的所有底层依赖类(即 NumberA
和 NumberB
)都会被实例化。
除了 Resolve
之外,我们还需要使用它们的具体实现来注册我们的数字接口(使用 RegisterType
)。因此,这提供了以松散耦合的方式延迟我们决定使用特定类直到运行时的能力。
在此示例中,每次在一个文本框中输入一个数字并单击“等于”命令按钮时,都会计算并显示总数。
关注点
此示例为 Sum
属性使用 OneWay 绑定,但为两个数字属性使用 TwoWay 绑定。这允许我们更新总和,而无需在按钮单击事件处理程序中使用任何代码。每次在一个文本框内更改文本并且它们失去焦点时,都会更新底层源。
历史
- 初始版本 - 2009 年 5 月 30 日。