zoukankan      html  css  js  c++  java
  • Unity Application Block Handson Lab for EnterLib 5.0:Lab 4Configuring Containers[Translation]

    实验估计时间:15mins

    介绍

    在该实验中,你将会练习使用Unity的更多特性:泛型装饰链、覆盖和数组注入。

    实验中用到的应用程序是实验三的升级版,添加了第三方框架persistence,能够存储证劵信息。这个persistence框架中定义了泛型接口IRepository<>和实体泛型类DebugRepository<>。

    开始之前,先在这里下载代码。

    任务1:配置开泛型与闭泛型

    Unity container可以配置使用闭泛型,就像使用非泛型类型和开泛型一样。在下面的case中,只要没有特殊的闭泛型,任何开泛型都可以替代闭泛型的配置。

    具体操作

    在StockTickerPresenter.cs文件中,StockTickerPresenter的构造函数中,添加合适的repository。

    public StocksTickerPresenter(
        IStocksTickerView view,
        IStockQuoteService stockQuoteService,
        IRepository<StockQuote> repository)
    {

    并添加SaveQuote方法:

    private void SaveQuote(StockQuote updatedQuote)
    {
        try
        {
            this.repository.Save(updatedQuote);
        }
        catch (RepositoryException e)
        {
            this.logger.Log(
                string.Format(
                    "Error saving the updated quote for '{0}': {1}",
                    updatedQuote.Symbol,
                    e.Message),
                TraceEventType.Warning);
        }
    }

    再来看配置文件app.config。跟上个实验一样,StocksTickerPresenter只有一个构造函数,默认的注入规则会找到presenter的唯一一个构造函数。现在,只要注册新的参数IRepository<StockQuote>就ok了,在配置文件中添加:

    <register type="IRepository[StockQuote]" mapTo="DebugRepository[StockQuote]"/>

    运行程序。

    下面来看看配置文件中改为开泛型的注册。

    将App.config改为如下:删除泛型里的StockQuote。

    <container>
      <register type="IStocksTickerView" mapTo="StocksTickerForm"/>
      <register type="IStockQuoteService" mapTo="RandomStockQuoteService">
        <property name="Logger"/>
      </register>
      <register type="IRepository[]" mapTo="DebugRepository[]"/>
      <register type="ILogger" mapTo="ConsoleLogger"/>
      <register name="UI" type="ILogger" mapTo="TraceSourceLogger">
        <lifetime type="singleton"/>
        <constructor>
          <param name="traceSourceName" value="UI"/>
        </constructor>
      </register>
      <register type="StocksTickerPresenter">
        <property name="Logger">
          <dependency name="UI"/>
        </property>
      </register>
    </container>

    运行程序,结构与之前的一样。

    任务2:泛型装饰链

    在任务1结束后,StocksTickerPresenter的UML图类似于下面:

    image

    在这任务2中,container将在presenter与repository之间加入一个装饰类,UML类似于:

    image

    在这个任务中,配置文件的部分配置将会被程序代码用RegisterType和Resolve方法覆盖。这样的结果是,StocksTickerPresenter将用ValidatingRepository<StockQuote>代替DebugRepository<StockQuote>。混合的配置是允许的,因为API配置和配置文件是等效的。ValidatorRepository<>是装饰类,并由container负责来装饰它。

    ValidatingRepository类的构造函数接收两个参数,validator的作用由RandomStockQuoteValidator来实现。

    下面在Program.cs中实现RegisterType的方法:

    container.RegisterType(typeof(IRepository<>), typeof(ValidatingRepository<>), "validate");

    再注册ValidatorRepository会用到的Validator具体类:

    container.RegisterType(typeof(IRepository<>), typeof(ValidatingRepository<>), "validate")
        .RegisterType<IValidator<StockQuote>, RandomStockQuoteValidator>();

    使用覆盖方法Resolve StocksTickerPresenter:

    StocksTickerPresenter presenter
                        = container.Resolve<StocksTickerPresenter>(new ParameterOverride("repository", new ResolvedParameter<IRepository<StockQuote>>("validate")).OnType<StocksTickerPresenter>());

    运行程序,一段时间后,在ui.log中你会找到关于RepositoryException的error log。

    任务3:数组注入

    在任务3中,CompositeLogger会代替TraceSourceLogger被注入到StocksTickerPresenter。

    首先,在Program.cs中使用RegisterType方法将ILogger映射到CompositeLogger类。

    container.RegisterType(typeof(IRepository<>), typeof(ValidatingRepository<>), "validate")
        .RegisterType<IValidator<StockQuote>, RandomStockQuoteValidator>()
        .RegisterType<ILogger, CompositeLogger>("composite");

    再更改RegisterType方法,通过构造函数将CompositeLogger类中的ILogger接口映射到具体实例的数组:

    container.RegisterType(typeof(IRepository<>), typeof(ValidatingRepository<>), "validate")
        .RegisterType<IValidator<StockQuote>, RandomStockQuoteValidator>()
        .RegisterType<ILogger, CompositeLogger>("composite", new InjectionConstructor(new ResolvedArrayParameter(
            typeof(ILogger), new ResolvedParameter<ILogger>("UI"))));

    然后,在Resolve方法中覆盖属性Logger。

    StocksTickerPresenter presenter
        = container.Resolve<StocksTickerPresenter>(new ParameterOverride("repository", new ResolvedParameter<IRepository<StockQuote>>("validate")).OnType<StocksTickerPresenter>()
        , new PropertyOverride("Logger", new ResolvedParameter<ILogger>("composite"))
        );

    运行程序,这样所有的记录都在ui.log文件中了。

    随笔分类 -EnterLib

    Unity Application Block Hands-on Lab for Enter-Lib 5.0:Lab 4-Configuring Containers[Translation]

    2012-02-20 15:33 by 木木子, 597 visits, 网摘收藏编辑
     

    Unity Application Block Hands-on Lab for Enter-Lib 5.0:Lab 3-Using a Configuration File[Translation]

    2012-02-17 13:19 by 木木子, 863 visits, 网摘收藏编辑
     

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

    2012-02-16 14:18 by 木木子, 912 visits, 网摘收藏编辑
     

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

    2012-02-15 20:04 by 木木子, 792 visits, 网摘收藏编辑
     
  • 相关阅读:
    Exception in thread "main" java.util.MissingFormatArgumentException: Format specifier 's'
    抓报错SQL
    10.3.4 direct path read and direct path read temp
    武道与健身——北漂18年(80)
    jquery选择器 之 获取父级元素、同级元素、子元素
    JQuery Show()的几种效果 总有一种是你需要的
    Add method not implemented
    MySQL server version for the right syntax to use near 'info where info.stu_id = 1' at line 1
    Mapped Statements collection does not contain value for WaitMissionMapper.updateWait
    Cause: org.xml.sax.SAXParseException; lineNumber: 32; columnNumber: 14; 注释中不允许出现字符串 "--"
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2361963.html
Copyright © 2011-2022 走看看