您的位置:首页 > 移动开发 > Unity3D

Enterprise Library - Unity Application Block 学习手册(最新版) Part 2

2010-09-15 10:01 495 查看
本文演示Enterprise Library – Unity Application Block依赖注入模块的使用。本文练习配置container在运行时执行依赖注入,不需依赖于在类代码中做attributes标识和设置生命周期管理器。本文由http://blog.entlib.com 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供,欢迎交流。

练习二:通过配置使用Container容器
首先,打开Labs\Lab02\begin\StocksTicker 目录下的StockTicker.sln Solution项目文件。

为了提供依赖注入的配置,调用container的RegisterType方法将接收InjectionMember对象,InjectionMember是一个基类,继承类有InjectionProperty和InjectionConstructor,在下面会用到。

1. 更新container配置,重载默认的注入规则
(1)更新IStockQuoteService接口调用RegisterType方法的代码,使用InjectionProperty对象注入Logger属性,代码如下所示。
[align=left] using (IUnityContainer container = new UnityContainer())[/align]
[align=left] {[/align]
[align=left] container[/align]
[align=left] .RegisterType<IStocksTickerView, StocksTickerForm>()[/align]
[align=left] .RegisterType<IStockQuoteService, MoneyCentralStockQuoteService>([/align]
[align=left] new InjectionProperty("Logger"))[/align]
[align=left] .RegisterType<ILogger, ConsoleLogger>()[/align]
[align=left] .RegisterType<ILogger, TraceSourceLogger>("UI")[/align]
[align=left] .RegisterInstance(new TraceSource("UI", SourceLevels.All));[/align]
[align=left] [/align]
[align=left] StocksTickerPresenter presenter[/align]
[align=left] = container.Resolve<StocksTickerPresenter>();[/align]
[align=left] [/align]
[align=left] Application.Run((Form)presenter.View);[/align]
}

上述代码中配置的InjectionProperty对象表示名称为Logger的属性将被注入container。因为针对该属性没有进一步的配置,因此在获取注入该属性值时,解析该属性的类型ILogger。这和前一节Dependency attribute的使用一样。

(2)使用RegisterType方法设置StocksTickerPresenter类的注入,代码如下所示。
[align=left] using (IUnityContainer container = new UnityContainer())[/align]
[align=left] {[/align]
[align=left] container[/align]
[align=left] .RegisterType<IStocksTickerView, StocksTickerForm>()[/align]
[align=left] .RegisterType<IStockQuoteService, MoneyCentralStockQuoteService>([/align]
[align=left] new InjectionProperty("Logger"))[/align]
[align=left] .RegisterType<ILogger, ConsoleLogger>()[/align]
[align=left] .RegisterType<ILogger, TraceSourceLogger>("UI")[/align]
[align=left] .RegisterInstance(new TraceSource("UI", SourceLevels.All))[/align]
[align=left] .RegisterType<StocksTickerPresenter>([/align]
[align=left] new InjectionProperty("Logger", new ResolvedParameter<ILogger>("UI")));[/align]
[align=left] [/align]
[align=left] StocksTickerPresenter presenter[/align]
[align=left] = container.Resolve<StocksTickerPresenter>();[/align]
[align=left] [/align]
[align=left] Application.Run((Form)presenter.View);[/align]
}

上述代码中,RegisterType方法没有用来操作类型映射,而仅仅用来注入Logger属性,正因为如此,仅有一个泛型类型的参数。此外,InjectionProperty还传入一个ResolvedParameter对象,该参数表示解析的对象实例名称(前面的示例代码不需要,因此省略了)。

这些配置已经足够成功运行范例程序了。InjectionConstructor attribute 触发TraceSourceLogger对象的创建,并注入到已注册的TraceSource实例。然而,在很多情况下,你不能够应用InjectionConstructor attribute或者你希望重载attribute和注入不同的对象。下一步,介绍如何使用RegisterType方法重载默认对象创建规则,使用不同的构造器来创建TraceSourceLogger 对象。

(3)更新ILogger 接口的RegisterType调用方法,使用UI名称来注入对仅含有有一个字符串参数的构造器调用,代码如下所示。
[align=left] using (IUnityContainer container = new UnityContainer())[/align]
[align=left] {[/align]
[align=left] container[/align]
[align=left] .RegisterType<IStocksTickerView, StocksTickerForm>()[/align]
[align=left] .RegisterType<IStockQuoteService, MoneyCentralStockQuoteService>([/align]
[align=left] new InjectionProperty("Logger"))[/align]
[align=left] .RegisterType<ILogger, ConsoleLogger>()[/align]
[align=left] .RegisterType<ILogger, TraceSourceLogger>("UI", [/align]
[align=left]new InjectionConstructor("UI"))[/align]
[align=left] .RegisterInstance(new TraceSource("UI", SourceLevels.All))[/align]
[align=left] .RegisterType<StocksTickerPresenter>([/align]
[align=left] new InjectionProperty("Logger", new ResolvedParameter<ILogger>("UI")));[/align]
[align=left] [/align]
[align=left] StocksTickerPresenter presenter[/align]
[align=left] = container.Resolve<StocksTickerPresenter>();[/align]
[align=left] [/align]
[align=left] Application.Run((Form)presenter.View);[/align]
}

InjectionConstructor 表明根据参数来决定调用哪一个构造函数。上述代码中,传入 UI 字符串,将调用仅仅有一个字符串参数的构造函数,并传入 UI 作为其参数,代替标识有InjectionConstructor attribute的构造函数。

删除对RegisterInstance的调用,因为这段代码已经没有必要了。
.RegisterInstance(new TraceSource("UI", SourceLevels.All)

2. 运行范例程序
现在运行范例程序,应该和之前的运行效果一样,但是现在不需要在源代码中添加一些额外的attributes。除了在TraceSourceLogger类的构造函数中还保留了InjectionConstructor attribute,其目的是说明了如何使用配置来覆盖attribute的标识。

使用RegisterType方法配置注入提供了一定的灵活性,这是使用attributes所没有的,然而,它也需要为container指定每一个注入。

3. 使用生命周期管理器(Lifetime manager)
Container使用lifetime manager有2个目的:
(1)在特定的上下文,确保解析一个特定的对象时总是返回相同的实例。
(2)合理释放解析的对象。
下面的练习中,内置的ContainerControlledLifetimeManager将用来释放TraceSourceLogger对象。

更新TraceSourceLogger类实现IDisposable接口
目前实现的TraceSourceLogger类在每一个消息记录日志后,都需要调用flush方法,并且不会关闭。在本练习中,该类将更新为实现IDisposable接口,正确关闭TraceSource。
(1)打开Loggers\TraceSourceLogger.cs文件
(2)添加TraceSourceLogger类实现IDisposable接口,如下所示。
(3)删除Log方法中调用Flush方法的代码。
public void Log(string message, TraceEventType eventType)
{
this.traceSource.TraceEvent(eventType, 0, message);
// this.traceSource.Flush(); --- 删除这行代码
}
(4)添加实现IDisposable接口的Dispose方法,代码如下所示。
[align=left] public void Dispose()[/align]
[align=left] {[/align]
[align=left] if (this.traceSource != null)[/align]
[align=left] {[/align]
[align=left] this.traceSource.TraceInformation("Shutting down logger");[/align]
[align=left] this.traceSource.Close();[/align]
[align=left] this.traceSource = null;[/align]
[align=left] }[/align]
}
上述代码记录shutting down消息,然后关闭trace source对象。

更新container对TraceSourceLogger类配置调用,使用Lifetime manager
更新对UI - ILogger接口的RegisterType调用方法,传入一个新的ContainerControlledLifetimeManager对象,代码如下所示。
[align=left] using (IUnityContainer container = new UnityContainer())[/align]
[align=left] {[/align]
[align=left] container[/align]
[align=left] .RegisterType<IStocksTickerView, StocksTickerForm>()[/align]
[align=left] .RegisterType<IStockQuoteService, MoneyCentralStockQuoteService>([/align]
[align=left] new InjectionProperty("Logger"))[/align]
[align=left] .RegisterType<ILogger, ConsoleLogger>()[/align]
[align=left] .RegisterType<ILogger, TraceSourceLogger>([/align]
[align=left] "UI", [/align]
[align=left] new ContainerControlledLifetimeManager(),[/align]
[align=left] new InjectionConstructor("UI"))[/align]
[align=left] .RegisterType<StocksTickerPresenter>([/align]
[align=left] new InjectionProperty("Logger", new ResolvedParameter<ILogger>("UI")));[/align]
[align=left] [/align]
[align=left] StocksTickerPresenter presenter[/align]
[align=left] = container.Resolve<StocksTickerPresenter>();[/align]
[align=left] [/align]
[align=left] Application.Run((Form)presenter.View);[/align]
}

lifetime manager是RegisterType方法的一个可选参数。

再次运行范例程序,按照前面的操作,输入GM/MSFT等等股票代码,最后关闭主窗口。接着,我们打开ui.log文件(在StocksTicker\bin\Debug目录),会发现在该文件的最后两行,有类似如下的记录。
UI Information: 0 : Shutting down logger
DateTime=2009-02-11T19:02:07.8990000ZZ

http://www.entlib.com专业ASP.NET电子商务平台小组,欢迎你继续访问Unity Application Block学习手册。

参考文档:
Unity Application Block Hands-On Labs for Enterprise Library
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐