该"交通灯"示例演示了如何在你的应用程序种使用Unity 应用程序块。他有一个非常简单的用户界面,"交通灯"有3种颜色来表示"禁止通行","允许通行"。在不同的时间段,它会显示红色,黄色,和绿色.你可以通过配置来决定他们多长时间进行切换显示。图1 显示了该程序的用户界面。
 图1 StopLight 快速入门的用户界面 |
该示例说明了Unity 应用程序块在以下方面的特性:
- 在容器中为不同类型注册他们的映射
- 通过注入Presenter的方式来实现MVP设计模式
- 用注入属性的方式将业务组件注入到对象之中
- 实现一个可配置的方式
图2 显示了该程序的类结构。
 图2 StopLight 快速入门架构、类和结构 |
在容器中为不同类型注册他们的映射"交通灯"示例中,运用了2个服务,他们是接口到具体实现的一个映射。这2个服务在Unity建立类的实体的时候被自动的注入到需要的具体的实现类。
接口ILogger由Unity映射到具体实现类TraceLogger,而接口IStoplightTimer由Unity映射到具体实现类RealTimeTimer.当应用程序开始运行的时候,他们的映射关系将被注册。
C#
IUnityContainer container = new UnityContainer()
.RegisterType<ILogger, TraceLogger>()
.RegisterType<IStoplightTimer, RealTimeTimer>();
Visual Basic
Dim container As IUnityContainer = New UnityContainer() _
.RegisterType(Of ILogger, TraceLogger)() _
.RegisterType(Of IStoplightTimer, RealTimeTimer)()
这样,将新建2个默认的映射,以便在向容器请求ILogger的时候返回一个新的TraceLogger的实例,而请求IStoplightTimer的时候,则返回一个RealTimeTimer的实例
注意:
在ServiceImplementations 文件夹中的TraceLogger组件暴露了一个Writhe的方法,该方法向当前应用程序的System.Diagnostics.Trace 实例中写入了一些说明信息。
RealTimeTimer 组件是一个"single-shot" 计数器.该组件在RealTimeTimer 里已经实现.它暴露出Duration 的属性,一个Start 方法,并且当他到达制定的时间的时候相应一个OnExpired 的事件。
在注册完所需的映射之后,代码必须根据应用程序的需要在子对象上使用依赖注入.应用程序的的父级对象是一个叫StoplightForm的WINDOWS窗体类.为了保证所有的依赖的对象被注入.Program类种的代码必须使用Unity的Resolve方法,该代码显示如下:
C#
Application.Run(container.Resolve());
Visual Basic
Application.Run(container.Resolve(Of StoplightForm)())
Appliction类的Run方法运行时接收一个object类型的参数.Unity 容器的Resolve方法生成一个StoplightForm 类的实例,对StoplightForm内所需的对象或对象的引用使用依赖注入。
通过注入Presenter的方式来实现MVP设计模式当应用程序启动,它将载入并显示StoplightForm,该窗体使用了MVP模式.因为它暴露了一个属性用于指向它关联的显示器,为了获取指向它自身的显示器,StoplightPresenter类通过一个Dependency 特性的声明,使用了属性注入.代码如下:
C#
public partial class StoplightForm : Form, IStoplightView
{
private StoplightPresenter presenter;
[Dependency]
public StoplightPresenter Presenter
{
get { return presenter; }
set
{
presenter = value;
presenter.SetView(this);
}
}
...
Visual Basic
Public Partial Class StoplightForm
Inherits Form
Implements IStoplightView
Private _presenter As StoplightPresenter
<Dependency()> _
Public Property Presenter() As StoplightPresenter
Get
Return _presenter
End Get
Set(ByVal value As StoplightPresenter)
_presenter = value
_presenter.SetView(Me)
End Set
End Property
...
这样确保了Unity在窗体显示出来以前能创建并显示出显示器.与对依赖注入的类型 StoplightPresenter,Unity 容器就能够在没有映射的情况下创建该对象。
视图暴露出一个事件处理,因此,显示器就可以用他来操作在窗体种的控件,并且能够访问到他们的值。
用属性注入的方式将业务组件注入到对象之中对于用户界面的显示器,StoplightPresenter类使用了Stoplight 的实例,Stoplight对象用于颜色的显示和交通灯的控制.Stoplight class 拥有3种颜色的枚举,通过暴露的Next 方法使应用程序在预定的时间改变交通灯的颜色,同时发出一个StoplightChangedHandler 事件.该事件的参数为LightChangedEventArgs 的实体,其包含着当前的颜色对象;
为了或者该类的对象,StoplightPresenter 暴露了他的一个属性和Dependency 特性,代码如下:
C#
private Stoplight stoplight;
[Dependency]
public Stoplight Stoplight
{
get { return stoplight; }
set { stoplight = value; }
}
Visual Basic
Private _stoplight As Stoplight
<Dependency()> _
Public Property Stoplight() As StopLight.Logic.Stoplight
Get
Return _stoplight
End Get
Set(ByVal value As StopLight.Logic.Stoplight)
_stoplight = value
End Set
End Property
Stoplight为注入所依赖的具体类,因此Unity 容器能够在没有创建映射的情况下创建对象。
用于维持StoplightTimer和ILogger引用的显示器同样对StoplightSchedule 有着依赖,它暴露了一些方法在改变颜色,并且在颜色改变的时候通过RealTimeTimer 对OnTimerExpired 事件作出了响应。
为了获取StoplightSchedule 的实例,StoplightPresenter 暴露了它自身的Schedule 属性,该属性使用Dependency特性.代码如下:
C#
private StoplightSchedule schedule;
[Dependency]
public StoplightSchedule Schedule
{
get { return schedule; }
set { schedule = value; }
}
Visual Basic
Private _schedule As StoplightSchedule
<Dependency()> _
Public Property Schedule() As StoplightSchedule
Get
Return _schedule
End Get
Set(ByVal value As Stoplight)
_schedule = value
End Set
End Property
此外,依赖类是一个具体实现的类,在该过程里是StoplightSchedule,因此,容器能够在没有创建映射的情况下创建对象。
实现一个可配置的方式Stoplight 和 StoplightSchedule 类含有非实现类的的依赖关系.它们对实现ILogger接口的类有着依赖关系.同样的情况也出现在NullLogger 或者TraceLogger,运行时候,可以用代码来选择那个具体的类是需要实例化的.它可以使用任何实现了ILogger接口的类,ILogger接口仅仅就一个Write方法,该方法在输出的时候写入了一个消息;
下面是一个可插拔的结构,在运行的时候才选择实现类,然后将该类根据容器组件种的注册映射注入到应用程序中,在快速入门的例子将 ILogger 接口通过RegisterType< ILogger, TraceLogger>()映射到TraceLogger类.所以,要使用不同的实现类,开发者不得不改变映射关系.比如,要实例化ReallyFastLogger,开发者就得改变映射为RegisterType< ILogger, ReallyFastLogger>()。
另外,通过使用配置文件来搭建Unity 容器或者通过从其他配置源中读取配置信息,开发者就可以允许用户不用再次编译代码的情况下来改变具体的类的映射关系。
Stoplight 和StoplightSchedule 通过暴露Logger 的属性,将映射到logger 的类强制注入,代码如下:
C#
private ILogger logger;
[Dependency]
public ILogger Logger
{
get { return logger; }
set { logger = value; }
}
Visual Basic
Private _logger As ILogger
<Dependency()> _
Public Property Logger As ILogger
Get
Return _logger
End Get
Set(ByVal value As ILogger)
_logger = value
End Set
End Property
顶部