代码改变世界

Unity Application Block Hands-on Lab for Enter-Lib 5.0:Lab 1-Using a Unity Container[Translation]

2012-02-15 20:04  木木子  阅读(1349)  评论(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,更刚开始一样了~