代码改变世界

Unity Application Block Hands-on Lab for Enter-Lib 5.0:Lab 2-Using the Configuration API[Translation]

2012-02-16 14:18  木木子  阅读(1333)  评论(0编辑  收藏  举报

实验估计时间: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

更多信息关于生命周期管理器见http://msdn.microsoft.com/en-us/library/ff660872(v=PandP.20).aspx