实验估计时间:20mins
介绍
在这次实验中,你将会练习在运行时通过相关注入来配置Container,而不是依赖于Attributes。并且学习生命周期管理。先在这里下载代码。
任务1:使用API配置Container
更改Container的配置方法,覆盖默认的注入规则
在这个任务中,主要是增加和修改RegisterType方法来更改配置Container的方式。
首先,修改RandomStockQuoteService的RegisterType方法,传入参数InjectionMember类。Member类是一个基类,在这次试验中主要用到InjectionProperty和InjectionConstructor。关于“InjectionProperty和Parameter的注册”更多的信息见于http://msdn.microsoft.com/en-us/library/ff660882(v=PandP.20).aspx。
打开Program.cs文件
更改IStockQuoteService接口的RegisterType方法,在改方法中通过InjectionProperty注册Logger属性,代码如下:
container
.RegisterType<IStocksTickerView, StocksTickerForm>()
.RegisterType<IStockQuoteService, RandomStockQuoteService>(new InjectionProperty("Logger"))
.RegisterType<ILogger, ConsoleLogger>()
.RegisterType<ILogger, TraceSourceLogger>("UI")
.RegisterInstance(new TraceSource("UI", SourceLevels.All));
在上述代码中的InjectionProperty的意思是指名为"Logger”的类需要被注入,由于没有对该属性特殊的说明,在获取没有命名的ILogger实例会被调用。这跟上个实验的添加Dependency Attribute类似的。
然后,使用RegisterType方法注入StockTickerPresenter类,代码如下:
container
.RegisterType<IStocksTickerView, StocksTickerForm>()
.RegisterType<IStockQuoteService, RandomStockQuoteService>(new InjectionProperty("Logger"))
.RegisterType<ILogger, ConsoleLogger>()
.RegisterType<ILogger, TraceSourceLogger>("UI")
.RegisterInstance(new TraceSource("UI", SourceLevels.All))
.RegisterType<StocksTickerPresenter>(new InjectionProperty("Logger", new ResolvedParameter<ILogger>("UI")));
在这里,ResolvedParameter的作用是指定调用实例的name。
现在可以正常运行程序了,但是注意下TraceSourceLogger类中还是使用了[InjectionConstructor]Attribute。现实中存在很多cases不能使用Attributes或者你希望通过注入代替Attributes的功能。下面来看下怎么使用RegisterType方法创建一个TraceSourceLogger。
代码如下:
container
.RegisterType<IStocksTickerView, StocksTickerForm>()
.RegisterType<IStockQuoteService, RandomStockQuoteService>(new InjectionProperty("Logger"))
.RegisterType<ILogger, ConsoleLogger>()
.RegisterType<ILogger, TraceSourceLogger>("UI", new InjectionConstructor("UI"))
//.RegisterInstance(new TraceSource("UI", SourceLevels.All))
.RegisterType<StocksTickerPresenter>(new InjectionProperty("Logger", new ResolvedParameter<ILogger>("UI")));
上述代码中的InjectionConstructor指明哪个构造函数被调用,在这里是调用了public TraceSourceLogger(string traceSourceName)这个构造函数。更多的信息关于注入参数和属性值见http://msdn.microsoft.com/en-us/library/ff660882(v=PandP.20).aspx
现在可以完美的运行程序了[不依赖Attributes]。
任务2:使用生命周期控制器
生命周期有两个用处:
在上下文中,确定使用的是同一个实例;
适合的配置实例Dispose。
在该任务中,创建一个ContainerControlledLifetimeManager去DisposeTraceSourceLogger。
TraceSourceLogger每次信息的登记后没有实现关闭。先,让该类实现IDisposable接口。
代码如下:
增加继承IDisposable接口:
public class TraceSourceLogger : ILogger,IDisposable
{
在Log方法中删去this.traceSource.Flush();
public void Log(string message, TraceEventType eventType)
{
this.traceSource.TraceEvent(eventType, 0, message);
//this.traceSource.Flush();
}
增加Dispose方法实现IDisposable接口方法:
public void Dispose()
{
if (this.traceSource != null)
{
this.traceSource.TraceInformation("Shutting down logger"); this.traceSource.Close(); this.traceSource = null;
}
}
接下来,在Program.cs中更改Container的配置信息。
container
.RegisterType<IStocksTickerView, StocksTickerForm>()
.RegisterType<IStockQuoteService, RandomStockQuoteService>(new InjectionProperty("Logger"))
.RegisterType<ILogger, ConsoleLogger>()
.RegisterType<ILogger, TraceSourceLogger>("UI",new ContainerControlledLifetimeManager(), new InjectionConstructor("UI"))
//.RegisterInstance(new TraceSource("UI", SourceLevels.All))
.RegisterType<StocksTickerPresenter>(new InjectionProperty("Logger", new ResolvedParameter<ILogger>("UI")));
运行程序,然后关闭,在ui.log最后条信息为:
UI Information: 0 : Shutting down logger
DateTime=2012-02-16T06:10:29.0471374Z