Unity Application Block Hands-on Lab for Enter-Lib 5.0:Lab 1-Using a Unity Container[Translation]
2012-02-15 20:04 木木子 阅读(1356) 评论(5) 编辑 收藏 举报本实验时间估计:15mins
介绍
在这次实验中,你将练习使用Unity创建应用程序。主要内容是修改一个简单的证劵报价器应用程序,使该应用程序中的构造函数与属性通过Unity创建。
证劵报价器
代码这里下载。
运行或者调试应用程序。运行结果,打开一个窗口和一个控制台。控制台显示的是应用程序运行时记录的信息。
在程序窗口中,你可以输入股票符号,只有字母组成,点击Subscribe按钮,同时选择Refresh,窗口会显示你加入股票的最新信息。窗口会定时更新。运行结果如下:
同时,在\bin\Debug目录下还有一个文件,记录着操作信息。
应用程序的UML
该程序使用Model-View-Presenter(MVP)模式创建。具体UML如下:
任务1:使用Container
在该任务中,程序原始代码将会被更改为使用Unity Container来创建和连接程序的实体类,代替直接调用类的构造函数和属性。
加入引用:Microsoft.Practices.Unity。
打开Program.cs文件。
增加using Microsoft.Practices.Unity的命名空间。
用UnityContainer中的Resolve替换直接使用构造函数创建StockTickerPresenter,如下:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
using (IUnityContainer container = new UnityContainer())
{
StocksTickerPresenter presenter = container.Resolve<StocksTickerPresenter>();
Application.Run((Form)presenter.View);
}
}
Unity实现了IDisposable接口,可以使用using语句。
调试程序,程序会被一个ResolutionFailedException中止。这是由于StocksTickerPresenter的构造函数需要IStocksTickerView和IStockQuoteService,在调用该构造函数时,IStocksTickerView不能被实例化。
使用RegisterType方法加入需要的类型映射。代码如下:
using (IUnityContainer container = new UnityContainer())
{
container.RegisterType<IStocksTickerView, StocksTickerForm>()
.RegisterType<IStockQuoteService, RandomStockQuoteService>();
StocksTickerPresenter presenter = container.Resolve<StocksTickerPresenter>();
Application.Run((Form)presenter.View);
}
再次调试程序
程序正常运行,但是缺少了Console的显示和ui.log文件的信息记录。
任务 2:使用Attributes注入
Attributes可以更改注入方式。使用Attributes可以属性注入和方法注入。
建立MoneyCentralStockService类的Logger属性的注入。
打开StockQuoteService\MoneyCentralStockQuoteService.cs文件[本人使用的是RandomStockQuoteService]
增加using Microsoft.Practices.Unity。
给Logger属性加入[Dependency]Attribute。
private ILogger logger;
[Dependency]
public ILogger Logger
{
get { return logger; }
set { logger = value; }
}
添加类型注册。
由于Container显示需要使用ILogger接口,需要添加类型映射。
打开Program.cs文件,更改代码为:
using (IUnityContainer container = new UnityContainer())
{
container.RegisterType<IStocksTickerView, StocksTickerForm>()
.RegisterType<IStockQuoteService, RandomStockQuoteService>()
.RegisterType<ILogger, ConsoleLogger>()
StocksTickerPresenter presenter = container.Resolve<StocksTickerPresenter>();
Application.Run((Form)presenter.View);
}
运行结果:窗口显示正常,控制台显示正常,但是ui.log没有记录信息,由于presenter类中的Logger类没有注入。
给StockTickerPresenter注入Logger属性
给StockTickerPresenter注入Logger属性,使用相同的Attribute[Dependency],但是Logger实例已经被注入过了,再注入一个Logger,需要标记为不同的Logger。
打开UI\StocksTickerPresenter.cs 文件
增加using Microsoft.Practices.Unity。
给Logger属性加上Attribute[Dependency(“UI”)]
同样地,在Program中注册类型。
调试程序,报错!由于TraceSourceLogger类有多个构造函数,Unity不能区分,因此必须指明调用哪个构造函数。
使用InjectionConstructor Attribute指明构造函数
打开Logger\TraceSourceLogger文件
增加using Microsoft.Practices.Unity
给其中一个构造函数添加Attribute。
[InjectionConstructor]
public TraceSourceLogger(TraceSource traceSource)
{
this.traceSource = traceSource;
}
回到Program中,用RegisterInstance方法指明在Resolving中会使用到的TraceSource。
using (IUnityContainer container = new UnityContainer())
{
container.RegisterType<IStocksTickerView, StocksTickerForm>()
.RegisterType<IStockQuoteService, RandomStockQuoteService>()
.RegisterType<ILogger, ConsoleLogger>()
.RegisterType<ILogger, TraceSourceLogger>("UI")
.RegisterInstance(new TraceSource("UI", SourceLevels.All));
StocksTickerPresenter presenter = container.Resolve<StocksTickerPresenter>();
Application.Run((Form)presenter.View);
}
运行程序,OK,更刚开始一样了~