【中英对照】【EntLib6】【Unity】实验1:使用一个Unity容器

Lab 1: Using a Unity Container

实验1:使用一个Unity容器

Estimated time to complete this lab: 15 minutes

估计完成时间:15分钟

Introduction

介绍

In this lab, you will practice using a Unity container to create application objects and wire them together. You will update a simple stocks ticker application to replace calls to constructors and property setters with requests to a properly configured Unity container.

在这个实验中,你将练习使用一个Unity容起来创建应用对象并将他们连贯在一起。你将更新一个简单的股票收录机应用,替换对构造函数的调用和属性的设置器,这需要恰当的配置Unity容器。

To begin this lab, open the StocksTicker.sln file located in the \Lab01\begin\StocksTicker folder.

要开始这个实验,打开位于\Lab01\begin\StocksTicker 文件夹下的StocksTicker.sln文件。

Running the Application

运行这个应用

Start by launching the application. To launch the application, on the Visual Studio Debug menu click Start Without Debugging or press Ctrl-F5. This opens a form and a console window. The console window opens to display the messages logged to the console while the application runs.

通过启动应用来开始。要运行应用,打开VS的调试菜单,单击菜单项 开始执行(不调试),或按下Ctrl-F5。这样就会打开一个Form窗体和一个控制台窗口。在应用运行期间控制台窗口会一直打开,并显示日志消息到控制台。

On the application form, you can enter stock quote symbols, consisting of only letters, and subscribe to them by clicking the Subscribe button. When the Refresh check box is selected, the form displays the latest information about each of the subscribed stock symbols. The form will flash each time an update for a stock symbol is received. The following figure illustrates a sample stocks ticker application.

在应用的Form窗体中,你可以输入股票报价符号,仅由字母组成,然后通过单击 订阅(subscribe) 按钮订阅他们。当刷新(Refresh)复选框被选中,窗体将会显示每个股票的最新信息。窗体每收到一个股票的更新信息就会刷新显示。下图示例了一个简单的股票收录机应用。

By default, the console is used to log information about the retrieval of updated quotes. The ui.log file (located in the StocksTicker\bin\Debug folder) contains information about the operations performed by the user interface (UI). After you close the application, you can review the contents of the log file.

在默认情况下,控制台用来显示接收到的更新的信息。而ui.log文件(位于StocksTicker\bin\Debug文件夹)包含关于在UI的的操作的记录。在你关闭应用之后,你可以重新查看日志文件里的内容。

Reviewing the Application

审视这个应用

The application is built by using the Model-View-Presenter (MVP) pattern. For information about the MVP pattern, see Separated Presentation on MSDN. The following figureError! Reference source not found. shows the classes involved in the application and their relationships.

这个应用使用了MVP模式来创建。关于MVP模式,可以见MSDN上的Separated Presentation。下图展示了应用涉及到的类和他们之间的关系。

The StocksTickerForm class implements the user interface, and the IStockQuoteService interface defines a service for retrieving current stock quotes, the RandomStockQuoteService is the concrete implementation of IStockQuoteService that is used in these labs. The ILogger interface and its implementations are used to log messages about the operation of the application. Finally, the StocksTickerPresenter class plays the presenter role.

StocksTickerForm类实现了UI,IStockQuoteService接口定义了一个获取当前股票符号的服务,在本实验中使用的RandomStockQuoteService类具体实现了IStockQuoteService接口。ILogger接口和他的实现类被用来记录关于应用的操作的日志消息。最后,StocksTickerPresenter扮演了presenter的角色。

All classes in the solution, including the presenter class, have constructors that take all of the required collaborators as parameters and properties where optional collaborators can be set. In the presenter‘s case, the required collaborators are its view and the service used to poll for updates, and logger is an optional collaborator.

解决方案中的所有类,包括presenter类,都有构造函数,包含了所有必需的构造信息作为参数,可选的构造者作为属性也是可以设置的。在presenter的情况下,必需的构造者是他的view和用来得到更新的服务,而日志器是可选构造者。

The static Program.Main() method creates all the involved objects in order and connects them together before launching the user interface (UI). The purpose of this lab is to replace the explicit creation of these objects with the use of a Unity container.

静态的Program.Main()方法创建了所有需要涉及的对象并在启动UI之前将它们连接在一起。这个实验的目的是通过对一个Unity 容器的使用来替换这些对象的显式创建。

Task 1: Using a Container

任务1:使用一个容器

In this task, the application‘s startup code will be updated to use a Unity container to create and connect the application‘s objects. This will replace the use of explicit calls to the classes‘ constructors and property setters.

在这个任务中,应用的启动代码将会被更新,使用一个Unity容器来创建和连接应用的对象。这将会替换对显式调用类的构造函数和属性的设置器的使用。

Adding References to the Required Assemblies

添加所需要的程序集

  1. In Solution Explorer, select the StocksTicker project, and then click Manage NuGet Packages on the Project menu.
  2. Select the "Online" option to view NuGet Packages available online.
  3. Search for EntLib6 in the search bar. Select Unity and click install.
  1. 在解决方案资源管理器中,选择StocksTicker项目,然后在项目菜单中单击管理NuGet程序包…项。
  2. 选择"联机"选项来查看所有在线能获取的NuGet包。
  3. 在搜索栏搜索EntLib6。选择Unity然后单击安装

  1. Click Accept on the License Acceptance window that pops up.
  1. 在弹出的许可证接受窗口中单击"接受"按钮。

Update the Startup Code to Use a Container

更新启动代码来使用一个容器

To update the startup code to use a container

要更新启动代码来使用一个容器

  1. Open the Program.cs file.
  2. Add a using directive for the Unity namespace.

    using Microsoft.Practices.Unity;

  3. 打开Program.cs文件。
  4. 添加一个指向Unity的命名空间引用。

    using Microsoft.Practices.Unity;

  5. Replace the creation of the instances (view, presenter, service, loggers) with a Resolve request to a new UnityContainer for the StocksTickerPresenter, as shown in the following highlighted code.
  6. 使用新的UnityContainer的Resolve方法替代实例(view, presenter, service, loggers)的创建,如下高亮的代码所示。

Unity containers implement the IDisposable interface. This enables the new code to take advantage of the using statement to dispose the new container. Lab 2 elaborates on the result of disposing a container.

Unity容器实现了IDisposable接口。这就允许新的代码使用using语法的优势来销毁创建的容器。实验2详细说明了销毁一个容器的过程和结果。

  1. Debug the application. To do this, click Start Debugging on the Visual Studio Debug menu or Press F5. The debugger will break with an unhandled ResolutionFailedException. This indicates that the attempt to resolve the StocksTickerPresenter has failed.
  2. 调试应用,单击 调试 菜单的开始调试项或按下F5键。调试器将会被一个未处理的ResolutionFailedException异常中断。这表示尝试确定StocksTickerPresenter失败了。

Although the container requires additional configuration to resolve the requested presenter, the messages for the ResolutionFailedException and its chain of InnerExceptions reveal some interesting details:

尽管容器需要进一步配置来确定需要的presenter,异常ResolutionFailedException和他的InnerExceptions消息揭示了一些有趣的细节:

  • The request to resolve the presenter is identified with the build key type = "StocksTicker.UI.StocksTickerPresenter", name = "(none)". In this case no name has been provided.
  • 确定presenter的需求被建立Key type = "StocksTicker.UI.StocksTickerPresenter", name = "(none)"标识。在这里,没有名字被提供。
  • The error occurred while resolving an object.
  • 错误发生在确定一个对象的时候。
  • The container determined that the constructor for StocksTickerPresenter with the signature (IStocksTickerView view, IStockQuoteService stockQuoteService) should be used to create the object, by using the autowiring rules.
  • 容器在使用默认的 autowiring规则的时候,确定StocksTickerPresenter的构造函数包含签名:(IStocksTickerView view, IStockQuoteService stockQuoteService)将被用来创建对象。
  • The root cause of the failure was the inability to build an instance of the IStocksTickerView interface to be the value for the view parameter in the chosen StocksTickerPresenter constructor. This problem is indicated by the InvalidOperationException
  • 导致这个失败的根本原因是在选择的构造函数中需要一个view作为其参数,而这个IStocksTickerView接口的对象无法创建。这个问题被InvalidOperationException异常指示出来的。

For information about Unity‘s autowiring rules, see the topic "Annotating Objects for Constructor Injection" in the Unity 3 documentation.

关于Unity的autowiring规则的信息,请看Unity 3 文档的Annotating Objects for Constructor Injection主题。

  1. Add the required type mappings by using the RegisterType method, as shown in the following highlighted code .This will enable the container to resolve the required objects.
  2. 通过使用RegisterType方法来添加必要类型映射,如下面所示的高亮代码。这将允许容器确定所需的对象。

Using the RegisterType method is primarily how you will set up a container. In addition to mapping abstract types to concrete ones as described in this step, you can use the RegisterType method to override the default injection rules and specify lifetime managers. The next exercises will show additional uses of the RegisterType method. For details about mapping types see the topic "Registering Types and Type Mappings" in the Unity 3 documentation.

使用RegisterType方法是你设置一个容器主要的内容。在这个步骤中描述了映射抽象类型到具体的类型,除此之位,你可以使用RegisterType方法来重载默认的注入规则和明确指定生命周期管理器。在下一个练习中将会展示RegisterType方法的额外用法。关于映射类型的更多详细信息,请柬Unity 3 文档的Registering Types and Type Mappings主题。

Running the Application

运行这个应用

Launch the application and use it. The application behaves as it did before the changes, except that no logging will be available in the console or the ui.log file.

运行应用并使用它。这个应用表现的跟修改前一样,除了没有日志信息出现在控制台窗口中和ui.log文件中。

Task 2: Using Attributes to Control Injection

任务2:使用特性来控制注入

Attributes can be used to override the default injection rules. In some cases, attributes are used to opt-in for injection on members ignored by the default rules. In other cases, attributes must be used to override the default rules or disambiguate cases where the rules cannot be used.

特性可以用来重载默认的注入规则。在某些情况下,特性被用来为成员选择注入,以忽略默认规则。在另一些情况下,特性必须用来重载默认规则,或在不能使用规则的情况下消除歧义。

Using Attributes to Enable Property Injection

使用特性来启用属性注入

It is very common to have the container set properties, in addition to passing in dependencies by using constructor arguments.

在通过构造函数参数来传递依赖项的方法之外,使用容器来设置属性也是非常通用的。

To set up injection for the Logger property on the RandomStockQuoteService class

在RandomStockQuoteService类为logger属性设置注入

  1. Open the StockQuoteServices\RandomStockQuoteService.cs file.
  2. Add a using directive for the Unity namespace.
  1. 打开StockQuoteServices\RandomStockQuoteService.cs文件。
  2. 添加一个指向Unity的命名空间引用。

    using Microsoft.Practices.Unity;

    1. Add the Dependency attribute to the Logger property, as shown in the following highlighted code.
  3. 添加Dependency特性到Logger属性上,如下所示高亮代码。

Adding a Type Registration to Resolve the ILogger Interface

添加一个类型注册器来确定ILogger接口

Because the container must now resolve the ILogger interface, a mapping from the interface to a concrete type must be added to the container. In this example, the interface will be mapped to the ConsoleLogger class in order to match the code originally used to wire-up the objects.

因为容器现在必需确定ILogger接口,一个指向接口的确定类型映射必需添加到容器中。在这个示例中,这个接口将被映射到ConsoleLogger类,以匹配原来的连接对象的代码。

To add a type registration to resolve the ILogger interface

添加一个类型注册器来确定ILogger接口

  1. Open the Program.csfile.
  2. Use the RegisterType method to map the ILogger interface to the ConsoleLogger class, as shown in the following highlighted code.
  1. 打开Program.cs 文件。
  2. 使用RegisterType方法来映射ILogger接口到ConsoleLogger类,如下所示高亮代码。

Running the Application

运行这个应用

Launch and use the application. Operations performed by the service are logged to the console, but UI operations are not logged to the console because the Logger property on the presenter class is still not injected.

运行并使用应用。服务的操作被记录到控制台,但是UI的操作没有被记录到控制台因为presenter里面的Logger属性还没有设置注入。

Setting Up Injection for the Logger Property on the StocksTickerPresenter Class

在StocksTickerPresenter类上设置Logger属性的注入

To inject the Logger property on the presenter class, this lab uses the same Dependency attribute. However, because a different logger instance is to be injected, you need a way to differentiate the loggers. The Unity container lets you register the same type multiple times, and give each registration a different name. When that dependency is resolved, the name can be used to specify exactly which instance you want. In this lab, you will use different names so that you can tell the difference between the logger objects.

要在presenter类上注入Logger属性,这个实验使用的是相同的Dependency特性。但是,因为不同的logger实例要被注入,你需要一种方式来区分Loggers。Unity容器允许你注册同一个类型多次,并给每个注册设置不同的名字。当依赖项被确定的时候,名称可以用来精确的指定哪个实例是你需要的。在这个实验中,你将使用不同的名字这样你就可以说明两个logger对象的不同了。

To set up injection for the Logger property on the StocksTickerPresenter class

在StocksTickerPresenter类上设置Logger属性的注入

  1. Open the UI\ StocksTickerPresenter.cs file.
  2. Add a using directive for the Unity namespace.
  1. 打开UI\ StocksTickerPresenter.cs文件。
  2. 添加一个指向Unity的命名空间引用。

    using Microsoft.Practices.Unity;

    1. Add the Dependency attribute to the Logger property using "UI" for the name, as shown in the following highlighted code.
  3. 在Logger属性上使用UI这个名字添加Dependency特性,如下高亮代码所示。

Adding a Type Registration to Resolve the ILogger Interface with the "UI" Name

使用"UI"这个名字来添加一个类型注册,以确定ILogger接口

To add a type registration to resolve the ILogger interface with the "UI" name

使用"UI"这个名字来添加一个类型注册,以确定ILogger接口

  1. Open the Program.cs file.
  2. Use the RegisterType method to map the ILogger interface to the TraceSourceLogger class with the "UI" name, as shown in the following highlighted code.
  1. 打开Program.cs 文件。
  2. 使用RegisterType方法来映射ILogger接口到TraceSourceLogger类,使用"UI"为名称,如下所示高亮代码。

Debugging the Application

调试这个应用

Launch the application. The debugger should break with an unhandled exception that indicates a new failure while trying to resolve the Logger property on the presenter to an instance of TraceSourceLogger. Examining the chain of InnerExceptions shows that the root cause of the failure is indicated with an InvalidOperationException and the message "The type TraceSourceLogger has multiple constructors of length 1. Unable to disambiguate." In this case, Unity‘s default injection rules cannot determine how to build the instance, so the container must be explicitly configured to build it.

运行应用。调试器将会被一个未处理的异常中断,其指示了在尝试确定presenter的Logger属性为TraceSourceLogger实例的时候产生了一个新的错误。仔细检查异常链中的InnerExceptions展示了导致这个错误的根本原因是一个InvalidOperationException异常,其消息是"The type TraceSourceLogger has multiple constructors of length 1. Unable to disambiguate."在这个情况下,Unity的默认注入规则不能确定如何创建实例,所以容器必需明确的配置如何构建他。

Indicating Which Constructor to Use When Building an Instance of TraceSourceLogger with the InjectionConstructor Attribute

用注入构造函数特性来指定当创建一个TraceSourceLogger实例使用哪个构造函数

This lab uses an attribute to indicate which of the two available constructors should be used to create an instance of the TraceSourceLogger class.

这个实验使用一个特性来指示已有的两个构造函数中的哪个来创建TraceSourceLogger类的实例。

To indicate which constructor to use when building an instance of TraceSourceLogger with the InjectionConstructor attribute

用注入构造函数特性来指定当创建一个TraceSourceLogger实例使用哪个构造函数

  1. Open the Loggers\TraceSourceLogger.cs file.
  2. Add a using directive for the Unity namespace.
  1. 打开Loggers\TraceSourceLogger.cs文件。
  2. 添加一个指向Unity的命名空间引用。

    using Microsoft.Practices.Unity;

    1. Add the InjectionConstructor attribute to the constructor that takes a TraceSource as its sole parameter, as shown in the following highlighted code.
  3. 添加一个InjectionConstructor特性到使用一个TraceSource作为其唯一参数的构造函数上,如下代码所示。

Adding an Instance Registration to Resolve the TraceSource Type

添加一个实例注册器来确定的TraceSource类型

After being pointed to one of the constructors, Unity‘s default injection rules take effect and an instance of the .NET Framework TraceSource class will be resolved to be used as the argument for the constructor call. Instead of instructing the container about how to build such an instance, which would be problematic since the class cannot be annotated with attributes, a pre-built instance will be supplied to the container.

在指定了一个构造函数之后,Unity的默认注入规则将起作用并且一个.NET Framework TraceSource类的实例将会被确认用来作为调用个构造函数时的参数。不是告诉容器如何创建一个这样的实例,因为这样可能会有问题如果这个类不能通过特性注释,取而代之的是,直接预先建立一个实例并提供给容器。(这里翻译我自己都觉得奇怪,我也没看懂)。

To add an instance registration to resolve the TraceSource type

添加一个实例注册器来确定的TraceSource类型

  1. 1. Open the Program.cs file.
  2. 2. Use the RegisterInstance method to indicate the instance to return when resolving the TraceSource class, as shown in the following highlighted code.
  1. 打开Program.cs 文件。
  2. 使用RegisterInstance方法来指示当确定TraceSource类的时候返回的实例,如下所示高亮代码。

Running the Application

运行这个应用

Launch and use the application. Now the application should work exactly as it did initially, with messages from the UI being logged to the ui.log file (located in the StocksTicker\bin\Debug folder) and messages from the service being logged to the console.

运行并使用这个应用。现在这个应用应该能够像最初那样正确的工作了,来自UI的消息将被记录到ui.log文件中(位于StocksTicker\bin\Debug文件夹)而来自服务的消息将会被记录到控制台。

Attributes are a convenient mechanism to override or disambiguate the container‘s default injection rules but can result in brittle dependencies. Using names can make particularly brittle dependencies because they get hard-coded in the source code. The next labs show alternative mechanisms to externalize the setup of a container without involving the objects being created. To verify you have completed the lab correctly, you can use the solution provided in the \Lab01\end\StocksTicker folder.

特性是一个方便的机制来重载或消除容器的默认注入规则但是可能导致零碎的依赖关系。使用名称将导致特别零碎的依赖因为他们使用硬编码方式存在源代码里面。在下一个实验中将展示台体的机制来具体化一个容器的安装避免涉及到对象的创建。你可以使用\Lab01\end\StocksTicker文件夹下提供的解决方案来来验证你完成的实验是否正确。

时间: 2024-10-15 16:15:33

【中英对照】【EntLib6】【Unity】实验1:使用一个Unity容器的相关文章

[转]从普通DLL中导出C++类 – dllexport和dllimport的使用方法(中英对照、附注解)

这几天写几个小程序练手,在准备将一个类导出时,发现还真不知道如果不用MFC的扩展DLL,是怎么导出的.但我知道dllexport可以导出函数和变量,而且MFC扩展DLL就算是使用了MFC的功能,但能否导出类应该也不是必须用MFC才能够做到,一定是有相应的机制可以实现.于是查了一下MSDN,发现这个机制简单的可怕,原来就和导出函数一样,把dllexport关键字加到类名前就可以了.估计和我一样的同学大有人在,把MSDN的相关文档翻译出来,附上我的注解,希望对大家有用. 评注程序均在Visual S

Welcome Docker to SUSE Linux Enterprise Server【水平有限,中英对照,求纠错】

  原文:Welcome Docker to SUSE Linux Enterprise Server Lightweight virtualization is a hot topic these days. Also called "operating system-level virtualization," it allows you to run multiple applications or systems on one host without a hypervisor

谷歌退出中国声明全文(中英对照版)A new approach to China

次针对Google的攻击无关,我们发现有第三方在定期的访问美国,中国,欧洲的许多人*权*支持者的Gmail帐户.对这些帐户的访问并不是通过Google认可的方式,大多是通过钓鱼欺诈手段,以及位于用户电脑中的恶意软件进行. We have already used information gained from this attack to make infrastructure and architectural improvements that enhance security for Go

Filesystem-Hierarchy-Standard(FHS) 文件系统层次结构标准2.3中英对照版(未完待续)

本想把原文翻译一遍,一来学习学习Linux的文件系统结构,二来熟悉下专业英语.经历了一个月之久,才翻译到一半.再也没有空闲时间待在学校了,不知道什么时间才能翻译完.先在这里发表一下,给有需要的同志们方便学习,也给自己一个提醒,告诉自己这里还有一件未完成的事..感謝大家支持 --------------------------------------以下是FHS-2.3正文内容----------------------------------------------- Filesystem Hi

计算机算法常用术语中英对照(分为两部分 其中一部分表格形式 )

第一部分 Data Structures 基本数据结构 Dictionaries 字典 Priority Queues 堆 Graph Data Structures 图 Set Data Structures 集合 Kd-Trees 线段树 Numerical Problems 数值问题 Solving Linear Equations 线性方程组 Bandwidth Reduction 带宽压缩 Matrix Multiplication 矩阵乘法 Determinants and Perm

[中英对照]User-Space Device Drivers in Linux: A First Look

如对Linux用户态驱动程序开发有兴趣,请阅读本文,否则请飘过. User-Space Device Drivers in Linux: A First Look | 初识Linux用户态设备驱动程序 User-Space Device Drivers in Linux: A First Look Mats Liljegren Senior Software Architect Device drivers in Linux are traditionally run in kernel spa

英语电影剧本大全(中英对照)

目     录 <泰坦尼克号>全部英文剧本 TV REPORTER: Treasure hunter Brock Lovett is best known for finding Spanish gold off islands in the best Caribbean. LIZZY: It’s OK, I’ll get you in a minutes. Come on. TV REPORTER: Now he is using Russian subs to reach the most

expdp/impdp 参数说明,中英对照

任意可以使用expdp/impdp的环境,都可以通过help=y看到帮助文档. 1.expdp参数说明 [[email protected] ~]$ expdp help=y Export: Release 11.2.0.3.0 - Production on Thu Sep 4 11:43:39 2014 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. The Data Pump expo

exp/imp 参数说明,中英对照

在任意可用exp/imp(导出/导入)命令的主机上,都可以通过exp/imp help=y查看所有的参数说明. 1.exp参数说明 [[email protected] ~]$ exp help=y Export: Release 11.2.0.3.0 - Production on Thu Sep 4 11:31:35 2014 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. You ca