<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>开源 ASP.Net/C# 博客平台 V3.2</title><link>http://blog.entlib.com/MainFeed.aspx?GroupID=2</link><description>http://blog.entlib.com</description><generator>EntLib.com Blog Version 3.0.0.0</generator><item><title>EntLib.com 电子商务系统 - 后台业务处理系统（BES）- 用户操作手册（PDF文档下载） </title><link>http://blog.entlib.com/entlibforum/archive/2009/12/30/entlib.com-bes-pdf.aspx</link><pubDate>Tue, 29 Dec 2009 18:35:02 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/12/30/entlib.com-bes-pdf.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/229.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/229.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/12/30/entlib.com-bes-pdf.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/229.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">EntLib.com 电子商务系统 - 后台业务处理系统（BES）- 用户操作手册（PDF文档下载） </source><description>&lt;div style="text-align: center"&gt;&lt;strong&gt;&lt;span id="forum__ctl0_TopicTitle"&gt;EntLib.com 电子商务系统 - 后台业务处理系统（BES）- 用户操作手册（PDF文档下载）&lt;/span&gt; &lt;/strong&gt;&lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" src="http://forum.entlib.com/useruploadfiles/entlibboy/image/eCommerce_BES/entlib_bes_usermanual_pdf.gif" /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;strong&gt;PDF 阅读器官方下载地址：&lt;/strong&gt;&lt;br /&gt;
&lt;a href="http://get.adobe.com/cn/reader/"&gt;http://get.adobe.com/cn/reader/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
如果您的电脑上没有安装 PDF 阅读器，可以到上述的adobe 官方网站上下载PDF 阅读器，然后在本地电脑上安装。&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;后台业务系统-用户操作手册-下载地址：&lt;br /&gt;
&lt;/strong&gt;&lt;a href="http://forum.entlib.com/Default.aspx?g=posts&amp;amp;t=813"&gt;http://forum.entlib.com/Default.aspx?g=posts&amp;amp;t=813&lt;/a&gt;&lt;br /&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/229.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>(2009.11.24 更新）电子商务后台业务处理系统（BES）- 用户操作手册</title><link>http://blog.entlib.com/rickie/archive/2009/11/24/entlib.com-bes-again.aspx</link><pubDate>Mon, 23 Nov 2009 11:45:25 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/rickie/archive/2009/11/24/entlib.com-bes-again.aspx</guid><wfw:comment>http://blog.entlib.com/rickie/comments/227.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/rickie/comments/commentRss/227.aspx</wfw:commentRss><comments>http://blog.entlib.com/rickie/archive/2009/11/24/entlib.com-bes-again.aspx#comment</comments><slash:comments>1</slash:comments><trackback:ping>http://blog.entlib.com/rickie/services/trackbacks/227.aspx</trackback:ping><source url="http://blog.entlib.com/rickie/rss.aspx">(2009.11.24 更新）电子商务后台业务处理系统（BES）- 用户操作手册</source><description>&lt;div style="text-align: center"&gt;&lt;strong&gt;EntLib.com 电子商务系统 - 后台业务处理系统（BES）- 用户操作手册&lt;/strong&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
第一部分主要介绍了后台业务处理系统中一些基本信息的设置和维护，如仓库信息、供应商的管理和维护、品牌管理和维护、送货方式、支付方式等等，详细内容请访问如下链接。&lt;br /&gt;
&lt;br /&gt;
&lt;a class="post_link" href="http://forum.entlib.com/Default.aspx?g=posts&amp;amp;t=648"&gt;&lt;font color="#41519a"&gt;EntLib.com 电子商务系统 - 后台业务处理系统（BES）- 用户操作手册-基本信息管理（1）&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
第二部分主要介绍了后台业务处理系统中产品信息管理模块。产品信息管理用来维护前台电子商务网站需要展示、销售的产品，主要有新增产品、产品复制或克隆、商品查询、相关商品设置、产品类别管理和定制前台产品目录等等功能。&lt;br /&gt;
&lt;br /&gt;
&lt;a class="post_link" href="http://forum.entlib.com/Default.aspx?g=posts&amp;amp;t=663"&gt;&lt;font color="#41519a"&gt;EntLib.com 电子商务系统 - 后台业务处理系统（BES）- 用户操作手册-产品信息管理（2）&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin: 17pt 0cm 16.5pt"&gt;第三部分主要介绍前台网站管理模块。前台网站管理包括如下一些内容：各级页面的产品展示，新闻公告，投票，搜索关键字等等，还包括与客户交互的，如客户反馈，产品评论，产品询问，商品到货通知，有奖问答等等，还有创建站外推广链接，优惠券管理和热销商品小类设置等等功能。&lt;br /&gt;
&lt;br /&gt;
&lt;a class="post_link" href="http://forum.entlib.com/Default.aspx?g=posts&amp;amp;t=697"&gt;&lt;font color="#41519a"&gt;EntLib.com 电子商务系统 - 后台业务处理系统（BES）- 用户操作手册-前台网站管理（3）&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
第四部分重点介绍电子商务系统的采购管理模块。采购是电子商务的供应链部分，与采购相关的模块有供应商管理、产品成本、和财务应付款等等功能。采购模块包括创建采购单、分摊费用、审核、入库、打印、查询、更新等等功能。&lt;br /&gt;
&lt;br /&gt;
&lt;a class="post_link" href="http://forum.entlib.com/Default.aspx?g=posts&amp;amp;t=700"&gt;EntLib.com 电子商务系统 - 后台业务处理系统（BES）- 用户操作手册-采购管理（4）&lt;/a&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin: 17pt 0cm 16.5pt"&gt;第五部分介绍了客户管理。客户管理模块记录了客户的注册信息，可以对指定的客户创建订单，更新客户信息，查看客户的积分历史记录和给客户添加积分。&lt;br /&gt;
&lt;br /&gt;
&lt;a class="post_link" href="http://forum.entlib.com/Default.aspx?g=posts&amp;amp;t=702"&gt;EntLib.com 电子商务系统 - 后台业务处理系统（BES）- 用户操作手册-客户管理（5）&lt;/a&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center; margin: 17pt 0cm 16.5pt"&gt;&lt;img alt="" src="http://blog.entlib.com/userfiles/rickie/image/bes/EntLib_eCommerce_backend_usermanual_s.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;img src="http://blog.entlib.com/rickie/aggbug/227.aspx" width="1" height="1" /&gt;</description><dc:creator>rickie</dc:creator></item><item><title>EntLib.com 电子商务系统 - 后台业务处理系统（BES）- 用户操作手册</title><link>http://blog.entlib.com/rickie/archive/2009/10/29/entlib.com-bes.aspx</link><pubDate>Wed, 28 Oct 2009 13:43:37 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/rickie/archive/2009/10/29/entlib.com-bes.aspx</guid><wfw:comment>http://blog.entlib.com/rickie/comments/226.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/rickie/comments/commentRss/226.aspx</wfw:commentRss><comments>http://blog.entlib.com/rickie/archive/2009/10/29/entlib.com-bes.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/rickie/services/trackbacks/226.aspx</trackback:ping><source url="http://blog.entlib.com/rickie/rss.aspx">EntLib.com 电子商务系统 - 后台业务处理系统（BES）- 用户操作手册</source><description>很多企业虽然展开了电子商务的业务，但由于不重视电子商务后台业务系统的流程分析和功能设计，这样会导致内部工作效率低下和很多工作不到位；另外，如果前台系统得不到后台业务系统的强力支持，最终也会导致客户满意度的下降，甚至客户群的流失。因此在电子商务的应用过程中，后台业务系统是非常关键的。&lt;br /&gt;
&lt;br /&gt;
EntLib.com 电子商务小组正在将后台业务处理系统的业务流程设计和功能分享出来。欢迎各位参考并提出意见。&lt;br /&gt;
&lt;div style="text-align: center"&gt;&lt;img width="400" height="233" alt="" src="/userfiles/rickie/image/bes/EntLib_eCommerce_backend_usermanual_s.gif" /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;a class="post_link" href="http://forum.entlib.com/Default.aspx?g=posts&amp;amp;t=648"&gt;EntLib.com 电子商务系统 - 后台业务处理系统（BES）- 用户操作手册（1）&lt;/a&gt;  --- 这一部分主要介绍和演示基本信息和数据管理，如支付方式、配送方式、省市区、权限管理、系统日志、供应商管理、品牌维护、仓库信息维护等等。&lt;br /&gt;
&lt;br /&gt;&lt;img src="http://blog.entlib.com/rickie/aggbug/226.aspx" width="1" height="1" /&gt;</description><dc:creator>rickie</dc:creator></item><item><title>电子商务网站的快速SEO解决方案 （葵花宝典 - PDF 文档下载）</title><link>http://blog.entlib.com/entlibforum/archive/2009/10/26/seo-pdf.aspx</link><pubDate>Sun, 25 Oct 2009 12:13:09 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/10/26/seo-pdf.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/225.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/225.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/10/26/seo-pdf.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/225.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">电子商务网站的快速SEO解决方案 （葵花宝典 - PDF 文档下载）</source><description>&lt;div style="text-align: center"&gt;&lt;strong&gt;电子商务网站的快速SEO解决方案 （葵花宝典 - PDF 文档下载）&lt;br /&gt;
&lt;/strong&gt;&lt;/div&gt;
&lt;div style="margin: 12pt 0cm 3pt"&gt; &lt;/div&gt;
&lt;div&gt;本文是EntLib.com 电子商务小组（&lt;a href="http://www.entlib.com/"&gt;http://www.EntLib.com&lt;/a&gt; ）针对国内电子商务网站关于SEO的一些思考和建议，提供了一些常用的、简单可行的SEO行动方案。更 高级别的、有针对性的优化方案需要深入分析和探讨。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;通过阅读本文，你可以实现如下目的：&lt;/div&gt;
&lt;ol type="1" style="margin-top: 0cm"&gt;
    &lt;li&gt;了解电子商务网站的一些基本SEO规范。&lt;/li&gt;
    &lt;li&gt;了解一些免费的网站管理员工具。&lt;/li&gt;
    &lt;li&gt;本文提供的SEO改进方案简单实用，实现成本很小，但长期效果明显，对网站业务非常有帮助。&lt;/li&gt;
&lt;/ol&gt;
&lt;div style="margin: 0cm 0cm 0pt 18pt"&gt; &lt;/div&gt;
&lt;div&gt;本文的大部分建议都基于SEO基本知识和我们的电子商务实践， 同时也参考业内的SEO专家文章和搜索引擎公司的官方文档。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文的一些场景以礼品中心网（&lt;a href="http://www.giftcenter.cn/"&gt;http://www.GiftCenter.cn&lt;/a&gt; ）的内容为主进行分析，在此表示感谢。这些SEO技术都已经在EntLib.com eCommerce 电子商务系统中予以实现，因此在技术上和实现上都没有问题。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文，对希望提高网站与用户和搜索引擎交互性的网站管理员们也一样会有帮助，所以我们对SEO相关内容进行整理完善，发表出来供大家参考。&lt;/div&gt;
&lt;br /&gt;
&lt;strong&gt;这里提供《电子商务网站的快速SEO解决方案》完整的PDF 文档下载！&lt;/strong&gt;&lt;br /&gt;
&lt;div style="text-align: center"&gt;&lt;br /&gt;
&lt;input src="http://forum.entlib.com/useruploadfiles/%E7%BE%8E%E5%A5%B3%E7%A8%8B%E5%BA%8F%E5%91%98/image/seo/seo_quicksolutionforecommerce_1.gif" width="667" height="535" type="image" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: left"&gt;该PDF 文档共有 21 页，下面是《电子商务网站的快速SEO解决方案》的目录。&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;欢迎下载！如有建议或反馈，欢迎回复！谢谢！&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
 &lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: center"&gt;&lt;input src="http://forum.entlib.com/useruploadfiles/%E7%BE%8E%E5%A5%B3%E7%A8%8B%E5%BA%8F%E5%91%98/image/seo/seo_quicksolutionforecommerce_2.gif" width="673" height="726" type="image" /&gt;&lt;/div&gt;
&lt;div style="text-align: left"&gt;&lt;strong&gt;下载地址：&lt;br /&gt;
&lt;/strong&gt;&lt;a class="post_link" href="http://forum.entlib.com/Default.aspx?g=posts&amp;amp;t=644"&gt;电子商务网站的快速SEO解决方案 （葵花宝典 - PDF 文档下载） --- EntLib.com 电子商务小组倾力制作&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
 &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/225.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>最新版 Enterprise Library 企业库 V4.1 中文学习手册 （提供整合的PDF文档下载）</title><link>http://blog.entlib.com/entlibforum/archive/2009/10/20/enterprise-library-v4.1-pdf.aspx</link><pubDate>Mon, 19 Oct 2009 13:50:08 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/10/20/enterprise-library-v4.1-pdf.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/224.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/224.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/10/20/enterprise-library-v4.1-pdf.aspx#comment</comments><slash:comments>4</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/224.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">最新版 Enterprise Library 企业库 V4.1 中文学习手册 （提供整合的PDF文档下载）</source><description>&lt;div align="center"&gt;&lt;b&gt;最新版 Enterprise Library &lt;/b&gt;&lt;b&gt;企业库 V4.1 &lt;/b&gt;&lt;b&gt;中文学习手册 &lt;/b&gt;&lt;b&gt;（提供整合的PDF&lt;/b&gt;&lt;b&gt;文档下载）&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Enterprise Library for .Net Framework 3.5 – EntLib v4.1 是patterns &amp;amp; practices 小组为.NET Framework 3.5 开发一套企业库，目前最新版本为v4.1，共包括9个Application Block，包括数据访问（Data Access Application Block）、异常管理（Exception Handling Application Block）、数据验证（Validation Application Block）、日志管理、依赖注入容器Unity、缓存管理、加密/解密、安全管理等等，对企业应用开发非常有帮助，也非常实用。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;a href="http://forum.entlib.com/Default.aspx?g=posts&amp;amp;t=576"&gt;&lt;img width="592" height="91" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/EnterpriseLibraryTopic.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://forum.entlib.com/"&gt;http://forum.EntLib.com&lt;/a&gt; 开源论坛小组根据EntLib Hands-On Labs提供了全套的中文学习手册，同时也提供了整合的PDF 文档下载 ---&lt;strong&gt; 共有133页&lt;/strong&gt;。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="690" height="487" src="/userfiles/entlibforum/image/EnterpriseLibrary/EnterpriseLibrary_hands_on_pdf.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;文档及下载地址：&lt;/div&gt;
&lt;div&gt;&lt;a href="http://forum.entlib.com/Default.aspx?g=posts&amp;amp;t=576"&gt;http://forum.entlib.com/Default.aspx?g=posts&amp;amp;t=576&lt;/a&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/224.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Security Application Block 学习手册（最新版） Part 2</title><link>http://blog.entlib.com/entlibforum/archive/2009/10/12/enterprise-library-security-application-block-part-2.aspx</link><pubDate>Sun, 11 Oct 2009 19:53:24 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/10/12/enterprise-library-security-application-block-part-2.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/223.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/223.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/10/12/enterprise-library-security-application-block-part-2.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/223.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Security Application Block 学习手册（最新版） Part 2</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Security Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 2&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本系列文章引导学习Enterprise Library - Security Application Block，并实践如何在不同的应用程序环境中使用Security Application Block的功能。前一节中，使用基于角色的授权来保护应用程序，这一节将练习使用AuthorizationProvider来保护应用程序。本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;使用AuthorizationProvider实现如下功能：&lt;/div&gt;
&lt;div&gt;（1）映射基于任务的授权为复杂的角色组合；&lt;/div&gt;
&lt;div&gt;（2）从应用程序代码中提取授权；&lt;/div&gt;
&lt;div&gt;&lt;b&gt; &lt;/b&gt;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习二：在应用程序中使用基于规则的授权（Rule-Based Authorization&lt;/b&gt;&lt;b&gt;） &lt;/b&gt;&lt;/div&gt;
&lt;div&gt;首先打开ex02\begin 目录下的BugSmak.sln 项目文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;使用Enterprise Library&lt;/b&gt;&lt;b&gt;配置管理工具&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;1. 使用Enterprise Library配置工具打开app.config配置文件，添加新的Security Application Block配置项。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="632" height="318" src="/userfiles/entlibforum/image/EnterpriseLibrary/Security/Security_2_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 选择Security Application Block | Authorization 节点，添加一个新的Authorization Rule Provider。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="582" height="279" src="/userfiles/entlibforum/image/EnterpriseLibrary/Security/Security_2_2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;设置Name =BugSmak Rules。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 选择 Security Application Block | Authorization | BugSmak Rules 节点，通过New | Rule菜单项添加新的Rule。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="591" height="311" src="/userfiles/entlibforum/image/EnterpriseLibrary/Security/Security_2_3.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 选择Security Application Block | Authorization | BugSmak Rules | Rule 节点，点击Expression属性后的… 按钮，弹出Rule Expression Editor对话框。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="632" height="274" src="/userfiles/entlibforum/image/EnterpriseLibrary/Security/Security_2_4.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;在Rule Expression Editor对话框中，设置如下属性：&lt;/div&gt;
&lt;div&gt;Rule Name = Raise Bug&lt;/div&gt;
&lt;div&gt;Expression = R:Developer OR R:Employee OR R:Manager&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="587" height="558" src="/userfiles/entlibforum/image/EnterpriseLibrary/Security/Security_2_5.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;用户必须是Developer、Employee、或Manager角色。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;5. 按照上述步骤，添加新的Rule和表达式。&lt;/div&gt;
&lt;div&gt;规则名称：Assign Bug&lt;span&gt;   --- &lt;/span&gt;表达式Expression：R:Manager&lt;/div&gt;
&lt;div&gt;规则名称：Resolve Bug&lt;span&gt;   --- &lt;/span&gt;表达式Expression：R:Developer OR R:Manager&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;设置完成后，界面如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="587" height="281" src="/userfiles/entlibforum/image/EnterpriseLibrary/Security/Security_2_6.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;6. 选择Security Application Block节点，设置如下属性。&lt;/div&gt;
&lt;div&gt;DefaultAuthorizationInstance = BugSmak Rules&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;最后保存好app.config配置文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;为应用程序添加基于任务的授权&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;1. 打开TaskForms \ RaiseBug.cs代码文件，其中关于PrincipalPermissions部分的硬编码已经注释掉了，这里将采用更加灵活的任务授权。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: green"&gt;//[PrincipalPermission(SecurityAction.Demand, Role = "Employee")]&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: green"&gt;//[PrincipalPermission(SecurityAction.Demand, Role = "Developer")]&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: green"&gt;//[PrincipalPermission(SecurityAction.Demand, Role = "Manager")]&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: #2b91af"&gt;RaiseBug&lt;/span&gt; Create()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// TODO: Check Authorization&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;b&gt;!&lt;span style="color: #2b91af"&gt;SecurityHelper&lt;/span&gt;.Authorized(&lt;span style="color: #2b91af"&gt;AuthRule&lt;/span&gt;.Raise)&lt;/b&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;SecurityException&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;RaiseBug&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;AssignBug.cs 和 ResolveBug.cs 有上述相似的代码。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 为项目文件添加对Security Application Block程序集的引用。&lt;/div&gt;
&lt;div&gt;Microsoft.Practices.EnterpriseLibrary.Security.dll&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 打开Security \ SecurityHelper.cs代码文件，添加如下命名空间的引用。&lt;/div&gt;
&lt;div&gt;using Microsoft.Practices.EnterpriseLibrary.Security;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 添加如下代码到Authorized方法。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;bool&lt;/span&gt; Authorized(&lt;span style="color: blue"&gt;string&lt;/span&gt; rule)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;bool&lt;/span&gt; authorized = &lt;span style="color: blue"&gt;false&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// TODO: Check rule-base authorization&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;IAuthorizationProvider&lt;/span&gt; ruleProvider;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;            ruleProvider = &lt;span style="color: #2b91af"&gt;AuthorizationFactory&lt;/span&gt;.GetAuthorizationProvider();&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt; &lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;            authorized = ruleProvider.Authorize(&lt;span style="color: #2b91af"&gt;Thread&lt;/span&gt;.CurrentPrincipal, rule);&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;return&lt;/span&gt; authorized;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;上述代码使用AuthorizationFactory 检索默认的authorization provider，授权提供者将依据规则，测试当前的principal（ role和identity）是否授权。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;5. 运行应用程序，分别以不同的用户Tom / Dick / Harry登录，验证不同的用户是否分配了不同的权限。&lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Security  Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Security Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/223.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Security Application Block 学习手册（最新版） Part 1</title><link>http://blog.entlib.com/entlibforum/archive/2009/10/12/enterprise-library-security-application-block-part-1.aspx</link><pubDate>Sun, 11 Oct 2009 19:38:44 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/10/12/enterprise-library-security-application-block-part-1.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/222.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/222.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/10/12/enterprise-library-security-application-block-part-1.aspx#comment</comments><slash:comments>1</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/222.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Security Application Block 学习手册（最新版） Part 1</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Security Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 1&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本系列文章引导学习Enterprise Library - Security Application Block，并实践如何在不同的应用程序环境中使用Security Application Block的功能。本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt;&lt;b&gt; &lt;/b&gt;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习一：保护应用程序 &lt;/b&gt;&lt;/div&gt;
&lt;div&gt;首先打开ex01\begin 目录下的BugSmak.sln 项目文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;为应用程序添加认证功能&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;运行应用程序，此时应用程序尚不能对用户进行认证。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;1. 打开Security \ SecurityHelper.cs代码文件，添加如下命名空间的引用。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; System.Web.Security; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 添加如下代码到Authenticate 方法。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;bool&lt;/span&gt; Authenticate(&lt;span style="color: blue"&gt;string&lt;/span&gt; username, &lt;span style="color: blue"&gt;string&lt;/span&gt; password)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;bool&lt;/span&gt; authenticated = &lt;span style="color: blue"&gt;false&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;b&gt;&lt;span style="color: #c00000"&gt;authenticated = Membership.ValidateUser(username, password);&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// TODO: Get Roles&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;return&lt;/span&gt; authenticated;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;LoginForm调用Authenticate方法对用户进行验证。Membership.ValidateUser方法执行验证操作。Membership system使用Provider 模式，因此应用程序不会绑定到特定的数据。ASP.NET 提供了2个membership provider：一个是使用Microsoft SQL Server作为数据源，另一个则使用Windows Active Directory。&lt;/div&gt;
&lt;div&gt;也可以创建定制的membership provider，范例程序将从XML文件中读取应用程序的成员信息。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 打开项目中的Security | Providers | ReadOnlyXmlMembershipProvider.cs代码文件。&lt;/div&gt;
&lt;div&gt;ReadOnlyXmlMembershipProvider继承MembershipProvider，是一个定制的membership provider，读取一个未加密的XML文件。虽然这不是一个好的设计，但对本练习而言是合适的。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 打开项目中的app.config 配置文件，检查membership provider 配置，认证数据源设定为Users.xml文件。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;membership&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;defaultProvider&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;b&gt;&lt;span style="color: #c00000"&gt;ReadOnlyXmlMembershipProvider&lt;/span&gt;&lt;/b&gt;"&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;providers&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;add&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;name&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;b&gt;&lt;span style="color: #c00000"&gt;ReadOnlyXmlMembershipProvider&lt;/span&gt;&lt;/b&gt;"&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;             &lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;type&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;b&gt;&lt;span style="color: #c00000"&gt;BugSmak.Security.Providers.ReadOnlyXmlMembershipProvider, BugSmak&lt;/span&gt;&lt;/b&gt;"&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;             &lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;description&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt;Read-only XML membership provider&lt;/span&gt;"&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;             &lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;xmlFileName&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;b&gt;&lt;span style="color: #c00000"&gt;Users.xml&lt;/span&gt;&lt;/b&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;      &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;providers&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="color: blue; font-size: 9pt"&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;membership&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;一旦你有定制的membership provider，你可以和配置ASP.NET provider一样，在应用程序中配置使用定制的membership provider。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;5. 打开Users.xml文件，可以看到已经运行添加了Tom / Dick / Harry 等等用户。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;6. 现在运行范例程序，以Tom / Dick / Harry 可以验证通过，并登录。&lt;/div&gt;
&lt;div&gt;本范例程序是一个简单的bug跟踪系统的框架，提供了如下功能点：提出Bug，分配Bug给开发人员，解决Bug。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="368" height="234" src="/userfiles/entlibforum/image/EnterpriseLibrary/Security/Security_1_1.gif" /&gt; &lt;/div&gt;
&lt;div&gt;7. 以Tom用户登录，选择 Tasks | Raise New Bug 菜单项，将看如下提示信息：&lt;/div&gt;
&lt;div&gt;Sorry, you aren’t allowed to access that form.&lt;/div&gt;
&lt;div&gt;同样地，在访问Assign Bug 和 Resolve Bug是也会出现上述提示信息，退出应用程序。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;为应用程序添加基于角色的授权&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;1. 打开TaskForms \ RaiseBug.cs文件，查看代码。&lt;/div&gt;
&lt;div&gt;RaiseBug窗口需要用户有Developer、Employee、或Manager角色之一。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;PrincipalPermission&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;SecurityAction&lt;/span&gt;.Demand, Role = &lt;span style="color: #a31515"&gt;"Employee"&lt;/span&gt;)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;PrincipalPermission&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;SecurityAction&lt;/span&gt;.Demand, Role = &lt;span style="color: #a31515"&gt;"Developer"&lt;/span&gt;)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;PrincipalPermission&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;SecurityAction&lt;/span&gt;.Demand, Role = &lt;span style="color: #a31515"&gt;"Manager"&lt;/span&gt;)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: #2b91af"&gt;RaiseBug&lt;/span&gt; Create()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// TODO: Check Authorization&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;RaiseBug&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;如果不具备必要的权限，将抛出SecurityException异常，由MainForm主窗体捕获。&lt;/div&gt;
&lt;div&gt;用户认证以及实现了，用户角色还没有实现，在后面的内容中，应用程序将配置使用RoleProvider来检索用户角色。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 打开Security \ SecurityHelper.cs 代码文件，为 Authenticate方法添加如下代码。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;bool&lt;/span&gt; Authenticate(&lt;span style="color: blue"&gt;string&lt;/span&gt; username, &lt;span style="color: blue"&gt;string&lt;/span&gt; password)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;bool&lt;/span&gt; authenticated = &lt;span style="color: blue"&gt;false&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            authenticated = &lt;span style="color: #2b91af"&gt;Membership&lt;/span&gt;.ValidateUser(username, password);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;b&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt; (!authenticated)&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;false&lt;/span&gt;;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt; &lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;IIdentity&lt;/span&gt; identity;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;            identity = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;GenericIdentity&lt;/span&gt;(username, &lt;span style="color: #2b91af"&gt;Membership&lt;/span&gt;.Provider.Name);&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt; &lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;string&lt;/span&gt;[] roles = &lt;span style="color: #2b91af"&gt;Roles&lt;/span&gt;.GetRolesForUser(identity.Name);&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;IPrincipal&lt;/span&gt; principal = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;GenericPrincipal&lt;/span&gt;(identity, roles);&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt; &lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Place user's principal on the thread&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Thread&lt;/span&gt;.CurrentPrincipal = principal;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;return&lt;/span&gt; authenticated;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;通过定制的RoleProvider(ReadOnlyXmlRoleProvider.cs)从Users.xml文件中检索用户角色，并创建一个新的principal，包含用户的identity和角色。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 打开app.config配置文件，查看role manager provider的配置，指定的数据源为Users.xml文件。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;roleManager&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;enabled&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt;true&lt;/span&gt;"&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;                 &lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;defaultProvider&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;b&gt;&lt;span style="color: #c00000"&gt;ReadOnlyXmlRoleProvider&lt;/span&gt;&lt;/b&gt;"&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;providers&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;add&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;name&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;b&gt;&lt;span style="color: #c00000"&gt;ReadOnlyXmlRoleProvider&lt;/span&gt;&lt;/b&gt;"&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;             &lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;type&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;b&gt;&lt;span style="color: blue"&gt;BugSmak.Security.Providers.ReadOnlyXmlRoleProvider, BugSmak&lt;/span&gt;&lt;/b&gt;"&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;             &lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;description&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt;Read-only XML role provider&lt;/span&gt;"&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;             &lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;xmlFileName&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;b&gt;&lt;span style="color: blue"&gt;Users.xml&lt;/span&gt;&lt;/b&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;      &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;providers&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="color: blue; font-size: 9pt"&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;roleManager&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 运行范例程序&lt;/div&gt;
&lt;div&gt;分别以不同的用户Tom / Dick / Harry依次登录，确认不同用户有不同的访问权限。&lt;/div&gt;
&lt;div&gt;Tom (Employee) -- Raise new bug&lt;/div&gt;
&lt;div&gt;Dick (Developer) -- Raise new bug and resolve bug&lt;/div&gt;
&lt;div&gt;Harry (Manager) -- Raise new bug, resolve bug, and assign bug&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="546" height="445" src="/userfiles/entlibforum/image/EnterpriseLibrary/Security/Security_1_2.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Security  Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Security Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/222.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Cryptography Application Block 学习手册（最新版） Part 2</title><link>http://blog.entlib.com/entlibforum/archive/2009/10/11/enterprise-library-cryptography-application-block-part-2.aspx</link><pubDate>Sat, 10 Oct 2009 10:52:00 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/10/11/enterprise-library-cryptography-application-block-part-2.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/221.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/221.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/10/11/enterprise-library-cryptography-application-block-part-2.aspx#comment</comments><slash:comments>3</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/221.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Cryptography Application Block 学习手册（最新版） Part 2</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Cryptography Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 2&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文继续Cryptography Application Block的学习，演示使用单向哈希算法（one-way hashing algorithm）加密存储在XML文件中的密码。本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt;&lt;b&gt; &lt;/b&gt;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习二：使用HashProvider&lt;/b&gt;&lt;b&gt;存储单向哈希密码 &lt;/b&gt;&lt;/div&gt;
&lt;div&gt;首先打开ex02\begin 目录下的UserUI.sln 项目文件，该应用程序提供了管理XML配置文件中的用户名和密码。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;范例应用程序简要描述&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;1. 运行范例程序，输入用户名Elmo，并保持默认的密码（P@ssw0rd）不变，点击OK按钮。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="569" height="446" src="/userfiles/entlibforum/image/EnterpriseLibrary/Cryptography/Cryptography_2_1.gif" /&gt; &lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;添加一个新的用户Zoe，重复上面的步骤。点击Save按钮，将保存上述信息到UserStore.config文件中。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 关闭应用程序，在Visual Studio 中打开UserStore.config配置文件，你会发现password以明文的形式保存在配置文件中。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;xml&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;version&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt;1.0&lt;/span&gt;"&lt;span style="color: red"&gt;encoding&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;utf-8&lt;/span&gt;"&lt;span style="color: blue"&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;configuration&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;configSections&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;section&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;name&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt;userStore&lt;/span&gt;"&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;UserStore.Configuration.UserSettings, UserStore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;configSections&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;userStore&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;users&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;add&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;name&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt;EntLib.com&lt;/span&gt;"&lt;span style="color: red"&gt;password&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;P@ssw0rd&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;add&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;name&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt;Forum&lt;/span&gt;"&lt;span style="color: red"&gt;password&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;P@ssw0rd&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;users&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;userStore&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;configuration&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;使用前一节的对称加密密钥对密码进行加密并不是一个好的方法，因为会影响密码的安全性。一般采用单向哈希算法，在和已存储的哈希密码（一般存储在数据库中）进行比较之前，先对输入的密码进行哈希。在这种情况下，即使数据库泄漏，密码仍然是安全的。&lt;/div&gt;
&lt;div&gt;在进行哈希算法之前，对密码添加额外的Salt，使得密码更难以破解。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;配置Hash Provider&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;1. 使用Enterprise Library的配置管理工具打开项目中的app.config配置文件。配置文件已经定义了2个配置源（Configuration Source），应用程序使用Enterprise Library 中配置的封装类来管理UserStore.config的位置和内容，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="619" height="293" src="/userfiles/entlibforum/image/EnterpriseLibrary/Cryptography/Cryptography_2_2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 右键点击应用程序配置文件，选择New | Cryptography Application Block，为配置文件添加Cryptography application block的配置节点。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="677" height="325" src="/userfiles/entlibforum/image/EnterpriseLibrary/Cryptography/Cryptography_2_3.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 选择Cryptography Application Block | Hash Providers 节点，添加 New | HashAlgorithm Provider，创建一个新的HashAlgorithm提供者。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="596" height="278" src="/userfiles/entlibforum/image/EnterpriseLibrary/Cryptography/Cryptography_2_4.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 在弹出的Type Selector 对话框中，选择SHA1Managed类型，然后点击OK按钮。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="685" height="488" src="/userfiles/entlibforum/image/EnterpriseLibrary/Cryptography/Cryptography_2_5.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;对于哈希算法，推荐使用SHA256Managed算法，该使用使用256位的哈希大小，而SHA1Managed哈希算法是160位，该算法也可以接受。MD4和MD5算法则不再推荐使用。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;5. 选择Cryptography Application Block | Hash Providers | SHA1Managed节点，设置如下属性：&lt;/div&gt;
&lt;div&gt;Name = PasswordHasher&lt;/div&gt;
&lt;div&gt;SaltEnabled = True&lt;/div&gt;
&lt;div&gt;最后，保存好配置文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;使用哈希算法&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;1. 选择Solution Provider中的UserStore项目，添加对Cryptography.dll程序集的引用。&lt;/div&gt;
&lt;div&gt;Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.dll&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 打开Security | HashHelper.cs文件（在UserStore项目中），添加如下命名空间的引用：&lt;/div&gt;
&lt;div&gt;using Microsoft.Practices.EnterpriseLibrary.Security.Cryptography;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 打开HashProvider类，添加如下代码：&lt;/div&gt;
&lt;div&gt;class HashHelper&lt;/div&gt;
&lt;div&gt;{&lt;/div&gt;
&lt;div&gt;&lt;span&gt;    private HashHelper() { }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;span&gt;    // TODO: Hash provider name must match app.config&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;&lt;span style="color: #c00000"&gt;    private const string hashProvider = "PasswordHasher";&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;span&gt;    . . .&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;}&lt;/div&gt;
&lt;div&gt;常量值必须匹配app.config配置文件中已命名的hash provider。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 修改CreateHash方法，如下所示。&lt;/div&gt;
&lt;div&gt;public static string CreateHash(string plainText)&lt;/div&gt;
&lt;div&gt;{&lt;/div&gt;
&lt;div&gt;&lt;span&gt;    string hash = null;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;span&gt;    // TODO: Hash the plain text&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;&lt;span style="color: #c00000"&gt;    hash = Cryptographer.CreateHash(hashProvider, plainText);&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;span&gt;    return hash;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;}&lt;/div&gt;
&lt;div&gt;在内存中的敏感数据需要尽快清除。在内存中的未加密数据存在安全风险。需要了解的是在内存中的数据也有可能写到硬盘上，因此操作系统可能将数据写到交换文件上。此外，如果系统崩溃，操作系统也会将内存中的数据写到硬盘上。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;5. 运行范例程序，重置Elmo的密码，点击Reset Password按钮，保留默认的密码（P@ssw0rd），然后点击OK按钮。UserStore.config配置文件中，当前明文保存的密码信息将替换为密码的哈希值。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="509" height="449" src="/userfiles/entlibforum/image/EnterpriseLibrary/Cryptography/Cryptography_2_6.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;6. 对用户Zoe也采用相同的步骤。&lt;/div&gt;
&lt;div&gt;7. 点击Save按钮，保存对UserStore.config的修改。&lt;/div&gt;
&lt;div&gt;8. 尝试更改Elmo的密码。点击Change Password按钮，输入默认的旧密码P@ssw0rd，然后数据新的密码，如EntLib，点击OK按钮。但是，此时会发生验证现有密码失败。为什么呢？看看后面的解释。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="598" height="445" src="/userfiles/entlibforum/image/EnterpriseLibrary/Cryptography/Cryptography_2_7.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;9. 点击Close按钮，关闭应用程序。&lt;/div&gt;
&lt;div&gt;10. 在Visual Stuido中打开UserStore.config文件，发现密码都已经哈希了。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;xml&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;version&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt;1.0&lt;/span&gt;"&lt;span style="color: red"&gt;encoding&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;utf-8&lt;/span&gt;"&lt;span style="color: blue"&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;configuration&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;configSections&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;section&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;name&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt;userStore&lt;/span&gt;"&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;UserStore.Configuration.UserSettings, UserStore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;configSections&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;userStore&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;users&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;add&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;name&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt;EntLib.com&lt;/span&gt;"&lt;span style="color: red"&gt;password&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;3kHeDQo7uDI6Pj7890is1EiNGGjBB6ImxpB5LJkCFV+hY3Kp&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;add&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;name&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt;Forum&lt;/span&gt;"&lt;span style="color: red"&gt;password&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;SBRc6JsFweEbxRfBStukevhur7RB3GpqaPLJRVymuK5WZ0e9&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;users&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;userStore&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;configuration&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;注意每种情况下，哈希值是不同的，即使实际的密码是相同的，这是因为额外的Salt。因此为了验证密码的有效性，我们不能简单应用对明文密码进行哈希计算，然后比较2个哈希字符串。&lt;/div&gt;
&lt;div&gt;11. 打开Security | HashHelper.cs文件（在UserStore项目中），修改CompareHash方法中的如下代码。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;bool&lt;/span&gt; CompareHash(&lt;span style="color: blue"&gt;string&lt;/span&gt; plainText, &lt;span style="color: blue"&gt;string&lt;/span&gt; hashedText)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;bool&lt;/span&gt; compare = &lt;span style="color: blue"&gt;false&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;b&gt;&lt;span style="color: #c00000"&gt;compare = Cryptographer.CompareHash(hashProvider, plainText, hashedText);&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;return&lt;/span&gt; compare;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;12. 再次运行应用程序，修改Elmo的密码 – 点击Change Password按钮，这次一定会成功。&lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Cryptography  Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Cryptography Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/221.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Cryptography Application Block 学习手册（最新版） Part 1</title><link>http://blog.entlib.com/entlibforum/archive/2009/10/11/enterprise-library-cryptography-application-block-part-1.aspx</link><pubDate>Sat, 10 Oct 2009 00:29:48 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/10/11/enterprise-library-cryptography-application-block-part-1.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/220.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/220.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/10/11/enterprise-library-cryptography-application-block-part-1.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/220.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Cryptography Application Block 学习手册（最新版） Part 1</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Cryptography Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 1&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本系列文章演示如何保护非配置文件中的信息，这里以一个模拟及时通讯（Instant Messenger）应用程序为例，升级应用程序以加密的消息，而不是明文消息来进行交谈。&lt;/div&gt;
&lt;div&gt;本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt;&lt;b&gt; &lt;/b&gt;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习一：加密和解密数据信息 &lt;/b&gt;&lt;/div&gt;
&lt;div&gt;首先打开ex01\begin 目录下的ChatterBox.sln 项目文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;范例应用程序简要描述&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;1. 以设计模式方式打开项目文件中的Chat.cs文件，如下图所示。&lt;/div&gt;
&lt;div&gt;该窗体用来发送和接收及时谈话信息，上面的文本框用来显示交谈记录，下面的文本框用来发送新的信息。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="338" height="481" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/Cryptography/Cryptography_1_1.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;2. 运行范例程序，将打开2个窗口（一个是Sam，另一个是Toby）。&lt;/div&gt;
&lt;div&gt;可以在这两个窗口之间传递消息。选择Tody 窗口，在Toby Says 对话框输入消息，然后点击Send按钮。同样的在Sam窗口进行相同操作。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;同时也会显示一个Console窗口，该窗口作为对话监视器，每一个消息都将在Console窗口显示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="688" height="578" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/Cryptography/Cryptography_1_2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;在两个窗口之间传递的消息为明文。下面将使用Cryptography Application Block的对称密钥（Symmetric Key）来加密和解密这些对话信息。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;添加加密和解密&lt;/div&gt;
&lt;div&gt;1. 为项目添加如下程序集&lt;/div&gt;
&lt;div&gt;Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.dll&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 打开Chat.cs代码文件，添加对如下命名空间的引用。&lt;/div&gt;
&lt;div&gt;using Microsoft.Practices.EnterpriseLibrary.Security.Cryptography;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 添加如下代码到Chat类中（红色粗体显示）&lt;/div&gt;
&lt;div&gt;public partial class Chat : Form&lt;/div&gt;
&lt;div&gt;{&lt;/div&gt;
&lt;div&gt;&lt;span&gt;    // TODO: Configuration symmetric algorithm provider name&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;    &lt;b&gt;&lt;span style="color: #c00000"&gt;private const string symmProvider = "ChatProvider";&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-indent: 21pt"&gt;. . .&lt;/div&gt;
&lt;div&gt;}&lt;/div&gt;
&lt;div&gt;上述常量必须匹配一个命名的对称加密提供者（Symmetric Cryptography Provider），本文后面部分会介绍，在App.config配置文件中symmetricCryptoProviders节。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 修改SendMessage方法，使用Cryptographer加密消息（红色粗体显示）&lt;/div&gt;
&lt;div&gt;private void SendMessage(string message)&lt;/div&gt;
&lt;div&gt;{&lt;/div&gt;
&lt;div&gt;&lt;span&gt;    // TODO: Encrypt message&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;   &lt;b&gt;&lt;span style="color: #c00000"&gt; string encrypted = Cryptographer.EncryptSymmetric(symmProvider, message);&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;span&gt;    // Raise SendingMessage Event&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;    if (this.SendingMessage != null)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;        this.SendingMessage(new MessageEventArgs(this._name, &lt;b&gt;&lt;span style="color: #c00000"&gt;encrypted&lt;/span&gt;&lt;/b&gt;));&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;}&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;5. 修改MessageReceived方法，使用Cryptographer方法解密消息（红色粗体显示）&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; MessageReceived(&lt;span style="color: #2b91af"&gt;MessageEventArgs&lt;/span&gt; args)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;string&lt;/span&gt; message = args.Message;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// TODO: Decrypt message&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;b&gt;&lt;span style="color: #c00000"&gt;string plainText = Cryptographer.DecryptSymmetric(symmProvider, message);&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;this&lt;/span&gt;.txtMessages.AppendText(&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                args.Sender + &lt;span style="color: #a31515"&gt;" says: "&lt;/span&gt; + &lt;b&gt;&lt;span style="color: #c00000"&gt;plainText&lt;/span&gt;&lt;/b&gt; + &lt;span style="color: #2b91af"&gt;Environment&lt;/span&gt;.NewLine);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;修改应用程序配置文件&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;1. 对应用程序添加app.config配置文件，并使用Enterprise Library 配置工具打开app.config配置文件，添加Cryptography Application Block配置项，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="645" height="313" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/Cryptography/Cryptography_1_3.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 选择 Cryptography Application Block | Symmetric Providers 节点，接着点击New | Symmetric Algorithm Provider 菜单项，如下图所示。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="619" height="233" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/Cryptography/Cryptography_1_4.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;随即弹出Type Selector 对话框，如下图所示。选择 RijndaelManaged类型，点击 OK 按钮。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="614" height="475" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/Cryptography/Cryptography_1_5.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;如果加密算法被破解或者易于受到攻击，则加密算法没有安全性。如果定制的算法没有经过测试验证，一般不太安全。因此，我们选择经过已公开的、众所周知的、且经受住多年攻击的加密算法。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;随着计算能力的提高，推荐的密钥长度也发生变化。目前，加密密钥长度在128位到256位认为是安全的。大多数现代的算法使用至少128位长的密钥。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;对称加密算法-AES，也称为Rijndael，推荐使用。该算法支持的密钥长度为128、192、和256位。DES算法不推荐使用。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 在Cryptographic Key 向导对话框中，选择Create a new key 选项，然后点击Next按钮，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="433" height="272" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/Cryptography/Cryptography_1_6.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;该向导将引导创建和保护加密密钥。点击Generate 按钮创建一个新的密钥，然后点击Next 按钮，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="446" height="280" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/Cryptography/Cryptography_1_7.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;在下一步保存加密文件的对话框中，将文件保存在本地的任何一个地方（你可以考虑保存在桌面），然后点击Next按钮，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="677" height="382" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/Cryptography/Cryptography_1_8.gif" /&gt; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;在向导的最后一步，选择User mode 或者 Machine mode模式，点击Finish 按钮，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="431" height="279" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/Cryptography/Cryptography_1_9.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;在创建密钥时，你可选择Machine mode 或者 User mode。&lt;/div&gt;
&lt;div&gt;Machine mode一般在如下情况下使用：&lt;/div&gt;
&lt;div&gt;（1）你的应用程序运行在自己的特定服务器上，且没有其他的应用程序。&lt;/div&gt;
&lt;div&gt;（2）你有多个应用程序运行在相同的服务器上，你希望这些应用程序能够共享敏感信息。&lt;/div&gt;
&lt;div&gt;User mode则一般在如下情况下采用：&lt;/div&gt;
&lt;div&gt;在共享的环境运行应用程序，但确保Server上其他应用程序不能访问该应用程序的敏感信息。在这种情况下，每个应用程序都在隔离的环境下运行，且应用程序的资源，如文件和数据库等等，都限制只有应用程序自身才可以访问。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 选择Cryptography Application Block | Symmetric Providers | RijndaelManaged 节点，设置如下属性： Name = ChatProvider&lt;/div&gt;
&lt;div&gt;ChatProvider是对称加密提供者的名称，在前面的代码中有使用到。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;最后，记得要保存好配置文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;运行应用程序&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;在Toby和Sam之间传递消息，在Console窗口发现消息已经加密了，但是在接收端，正确解密出明文信息。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="680" height="572" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/Cryptography/Cryptography_1_10.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;你或许会注意到在使用Cryptographer之后，应用程序会有些不稳定（如发生空白消息）。通常，我们需要在加密或解密字符串之前，需要添加一些代码进行检查。如，在SendMessage和MessageReceived方法中，检查字符串的长度是否为0。在MessageReceived方法，对解密的字符串，还需要检查长度是否为4个字节的整数倍，且仅含有有效Base64字符。这里为了简便，忽略了这些。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;添加错误处理&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;处理异常最好的办法是确保在最前面的地方添加检查代码，确保异常不要发生。首先，确保不要加密0长度的字符串。在项目Chat.cs文件中的SendMessage方法，添加如下代码。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; SendMessage(&lt;span style="color: blue"&gt;string&lt;/span&gt; message)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;b&gt;&lt;span style="color: #c00000"&gt;if ((message != null) &amp;amp;&amp;amp; (message.Trim().Length &amp;gt; 0))&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: green"&gt;// TODO: Encrypt message&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;string&lt;/span&gt; encrypted = &lt;span style="color: #2b91af"&gt;Cryptographer&lt;/span&gt;.EncryptSymmetric(symmProvider, message);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: green"&gt;// Fire SendingMessage Event&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: blue"&gt;this&lt;/span&gt;.SendingMessage != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: blue"&gt;this&lt;/span&gt;.SendingMessage(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;MessageEventArgs&lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;._name, encrypted));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Cryptography  Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Cryptography Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/220.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Caching Application Block 学习手册（最新版） Part 3</title><link>http://blog.entlib.com/entlibforum/archive/2009/09/30/enterprise-library-caching-application-block-part-3.aspx</link><pubDate>Tue, 29 Sep 2009 22:52:40 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/09/30/enterprise-library-caching-application-block-part-3.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/219.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/219.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/09/30/enterprise-library-caching-application-block-part-3.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/219.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Caching Application Block 学习手册（最新版） Part 3</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Caching Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 3&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文演示如何在不同的应用程序中使用Enterprise Library - Caching Application Block模块，下面介绍了使用后台线程来装载缓存。&lt;/div&gt;
&lt;div&gt;本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt;&lt;b&gt; &lt;/b&gt;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习三：实现后台异步缓存&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;首先打开ex03\begin 目录下的EmployeeBrowser.sln 项目文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;实现数据库服务器在线时，后台线程预先装载缓存&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;1. 打开项目中的EmployeeService.cs代码文件，添加如下2个方法，用来在后台装载缓存。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; PopulateCache()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;byte&lt;/span&gt;[] photoData = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;EmployeesDataSet&lt;/span&gt; dsEmployees = GetContactDetails();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (dsEmployees == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;ICacheManager&lt;/span&gt; cache = &lt;span style="color: #2b91af"&gt;CacheFactory&lt;/span&gt;.GetCacheManager();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;EmployeesDataSet&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;EmployeesRow&lt;/span&gt; employee &lt;span style="color: blue"&gt;in&lt;/span&gt; dsEmployees.Employees)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;if&lt;/span&gt; (!cache.Contains(employee.EmployeeID.ToString()))&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: #2b91af"&gt;EmployeeDataProvider&lt;/span&gt; dataProvider = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;EmployeeDataProvider&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    photoData = dataProvider.GetEmployeePhotoData(employee.EmployeeID);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;b&gt;cache.Add(employee.EmployeeID.ToString(), photoData);&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;delegate&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: #2b91af"&gt;PopulateCacheDelegate&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; BeginBackgroundLoad()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (!&lt;span style="color: #2b91af"&gt;ConnectionManager&lt;/span&gt;.IsOnline)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;PopulateCacheDelegate&lt;/span&gt; mi = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;PopulateCacheDelegate&lt;/span&gt;(PopulateCache);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            mi.BeginInvoke(&lt;span style="color: blue"&gt;null&lt;/span&gt;, &lt;span style="color: blue"&gt;null&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;BeginBackgroundLoad 方法使用delegate在后台线程启动PopulateCache方法。PopulateCache方法遍历所有的员工，并缓存对应的图片（注：这不是很安全，因为用户可能在另一个线程中添加或删除记录）。更好的办法是，选取部分记录，然后进行遍历并缓存。&lt;/div&gt;
&lt;div&gt;Caching Application Block在使用缓存时，确保线程安全，因此同时从多个线程访问时，是安全的。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 打开MainForm.cs代码文件，找到MainForm_Load方法，添加启动后台线程工作的代码。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; MainForm_Load(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;this&lt;/span&gt;.ToolStripLabel1.Text = &lt;span style="color: #2b91af"&gt;ConnectionManager&lt;/span&gt;.StatusText;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Load data into the 'EmployeesDataSet'.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;EmployeesDataSet&lt;/span&gt; tempDataset = &lt;span style="color: #2b91af"&gt;EmployeeService&lt;/span&gt;.GetContactDetails();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (tempDataset != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;this&lt;/span&gt;.EmployeesDataSet.Merge(tempDataset);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;           &lt;b&gt; &lt;span style="color: #2b91af"&gt;EmployeeService&lt;/span&gt;.BeginBackgroundLoad();&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;运行范例程序&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;1. 运行范例程序，现在不需要浏览任何员工，但需要等待约10秒，然后退出应用程序。&lt;/div&gt;
&lt;div&gt;在应用程序在线时，后台线程将缓存员工图片。缓存保存在独立的存储区域，但是使用和上一节不同的PartitionName（partitionName="EmployeeBrowser_ex03"），这样缓存内容不会相互干扰。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="667" height="276" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/caching/caching_3_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 打开ConnectionManager.cs代码文件，修改IsOnline属性，模拟应用程序处于离线状态。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;bool&lt;/span&gt; IsOnline&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;b&gt;&lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;false&lt;/span&gt;; }&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 再次运行范例程序，现在应用程序处于离线状态，不能访问数据库，但是所有员工的联系信息和图片都已经缓存了，因此可以顺利浏览所有员工信息。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="602" height="520" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/caching/caching_3_2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Caching Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Caching Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/219.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Caching Application Block 学习手册（最新版） Part 2</title><link>http://blog.entlib.com/entlibforum/archive/2009/09/29/enterprise-library-caching-application-block-part-2.aspx</link><pubDate>Mon, 28 Sep 2009 20:33:45 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/09/29/enterprise-library-caching-application-block-part-2.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/218.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/218.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/09/29/enterprise-library-caching-application-block-part-2.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/218.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Caching Application Block 学习手册（最新版） Part 2</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Caching Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 2&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文演示如何在不同的应用程序中使用Enterprise Library - Caching Application Block模块，下面介绍了使用持久化后台存储（缓存）和离线缓存过期策略。&lt;/div&gt;
&lt;div&gt;本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt;&lt;b&gt; &lt;/b&gt;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习二：持久化缓存&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;首先打开ex02\begin 目录下的EmployeeBrowser.sln 项目文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;实现离线缓存&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;1. 打开项目中的EmployeeService.cs代码文件，添加如下命名空间的引用：&lt;/div&gt;
&lt;div&gt;using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 找到代码中的GetContactDetails方法，添加如下代码：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: #2b91af"&gt;EmployeesDataSet&lt;/span&gt; GetContactDetails()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;EmployeesDataSet&lt;/span&gt; dsEmployees = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Attempt to retrieve from cache&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;ICacheManager&lt;/span&gt; cache = &lt;span style="color: #2b91af"&gt;CacheFactory&lt;/span&gt;.GetCacheManager();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            dsEmployees = (&lt;span style="color: #2b91af"&gt;EmployeesDataSet&lt;/span&gt;)cache[CACHE_KEY];&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Retrieve from dataProvider if not in Cache and Online&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (dsEmployees == &lt;span style="color: blue"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style="color: #2b91af"&gt;ConnectionManager&lt;/span&gt;.IsOnline)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;               &lt;span style="color: #2b91af"&gt;EmployeeDataProvider&lt;/span&gt; dataProvider = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;EmployeeDataProvider&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                dsEmployees = dataProvider.GetEmployees();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: green"&gt;// Expire in 2 days&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;AbsoluteTime&lt;/span&gt; expiry = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;AbsoluteTime&lt;/span&gt;(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;TimeSpan&lt;/span&gt;(2, 0, 0, 0));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                cache.Add(CACHE_KEY, dsEmployees,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: #2b91af"&gt;CacheItemPriority&lt;/span&gt;.High, &lt;span style="color: blue"&gt;null&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ICacheItemExpiration&lt;/span&gt;[] { expiry });&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;return&lt;/span&gt; dsEmployees;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;上述代码实现在应用程序在线的时候，连接数据库。返回的数据集对象将添加到缓存中，并充分利用重载的Add方法，指定缓存的优先级和缓存过期策略。在这种情况下，用户保留在本地机器上的员工数据将不能超过2天，可以减少员工将这些信息泄露给其他公司的可能性，因为如果缓存过期将删除这些数据。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 修改GetemployeePhoto方法，在应用程序离线的情况下，不要连接数据库检索员工信息。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Bitmap&lt;/span&gt; GetEmployeePhoto(&lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt; employeeId)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;byte&lt;/span&gt;[] photoData = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Attempt to retrieve from cache&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;ICacheManager&lt;/span&gt; cache = &lt;span style="color: #2b91af"&gt;CacheFactory&lt;/span&gt;.GetCacheManager();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            photoData = (&lt;span style="color: blue"&gt;byte&lt;/span&gt;[])cache[employeeId.ToString()];&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// TODO: Retrieve from dataProvider if not in Cache and Online&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (photoData == &lt;span style="color: blue"&gt;null&lt;/span&gt; &lt;b&gt;&lt;span style="background: yellow"&gt;&amp;amp;&amp;amp; &lt;span style="color: #2b91af"&gt;ConnectionManager&lt;/span&gt;.IsOnline&lt;/span&gt;&lt;/b&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;EmployeeDataProvider&lt;/span&gt; dataProvider = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;EmployeeDataProvider&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                photoData = dataProvider.GetEmployeePhotoData(employeeId);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                cache.Add(employeeId.ToString(), photoData);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// No data found.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (photoData == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Convert bytes to Bitmap&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt; ms = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt;(photoData))&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Bitmap&lt;/span&gt;(ms);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;配置持久化缓存&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;1. 使用Enterprise Library 的配置管理工具，打开app.config配置文件。&lt;/div&gt;
&lt;div&gt;2. 选择Caching Application Block | Cache Managers | Cache Manager 节点，然后选择 New | Isolated Storage 菜单项。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="623" height="279" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/caching/caching_2_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 选择Isolated Storage节点，设置PartitionName属性为 EmployeeBrowser。&lt;/div&gt;
&lt;div&gt;Partition Name允许多个缓存使用Isolated storage，相互之间不造成干扰。保存上述配置文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;运行范例程序&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;1. 浏览部分员工，这里会缓存员工图片信息，但是不要浏览所有员工信息，没有浏览的员工，其图片则没有缓存（方便下一步进行对比），然后关闭应用程序。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 打开项目中的ConnectionManager.cs代码文件，修改IsOnline属性，如下所示，模拟应用程序处于离线状态。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;bool&lt;/span&gt; IsOnline&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;false&lt;/span&gt;; }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }   &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;正常情况下，该类负责检测服务器的连接状态，判断是否Client处于在线状态，并连接数据库。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 再次运行范例程序，应用程序处于离线状态，不能访问数据库。现在需要从缓存中获取员工联系信息，包括员工图片，但是缓存中仅仅只有前面在线浏览过的员工图片信息，对于没有浏览过的员工信息，将仅仅显示员工信息，员工图片信息则无法显示，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/caching/caching_2_2.gif" /&gt; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Caching Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Caching Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/218.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Caching Application Block 学习手册（最新版） Part 1</title><link>http://blog.entlib.com/entlibforum/archive/2009/09/27/enterprise-library-caching-application-block-part-1.aspx</link><pubDate>Sat, 26 Sep 2009 23:15:31 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/09/27/enterprise-library-caching-application-block-part-1.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/217.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/217.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/09/27/enterprise-library-caching-application-block-part-1.aspx#comment</comments><slash:comments>1</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/217.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Caching Application Block 学习手册（最新版） Part 1</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Caching Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 1&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文演示如何在不同的应用程序中使用Enterprise Library - Caching Application Block模块，需要SQL Server数据库。其中包含如下三个示例：&lt;/div&gt;
&lt;div&gt;（1）使用Caching Block提供程序性能&lt;/div&gt;
&lt;div&gt;（2）持久化Caching&lt;/div&gt;
&lt;div&gt;（3）实现后台Caching&lt;/div&gt;
&lt;div&gt;通过本文的学习，你可以学会在应用程序中应用Caching机制，同时掌握在后台填充缓存。&lt;/div&gt;
&lt;div&gt;本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt;&lt;b&gt; &lt;/b&gt;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习一：使用Caching Block&lt;/b&gt;&lt;b&gt;提高应用程序性能&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;范例程序演示通过caching 来加快员工数据的现实，并持久化缓存，支持offline。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;打开ex01\begin 文件夹下的EmployeeBrowser.sln文件。然后，在SQL Server Management Studio界面打开 \Enterprise Library 4.1 HOL\CS\Caching\setup 目录下的CachingHOL.sql文件，执行里面的SQL脚本。该脚本在EntLibQuickStarts数据库中创建Employees表，并初始化部分数据。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;范例应用程序概述&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;本范例程序用来展示存储在数据库中的员工信息，包括显示员工的图片。尽管应用程序在启动的时候，装载所有的员工记录，但是并不装载所有的图片信息，而是在显示特定员工信息时，才装载对应的图片。这是因为图片数据量比较大，如果在启动应用程序时，装载所有的图片数据，会严重影响启动速度。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;检查MainForm.cs文件中的MainForm_Load 方法，该方法调用EmployeeService类，EmployeeService又调用EmployeeDataPrvoider类来获取员工数据，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="628" height="229" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/caching/caching_1_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;当前，EmployeeService仅仅直接依赖EmployeeDataProvider类，下面将强化利用Caching Block，在应用程序离线的情况下，也可以运行正常。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;选择EmployeeDataProvider.cs文件，在代码文件中找到GetEmployeePhotoData方法，GetEmployeePhotoData方法中特别添加了1秒的延迟，用来模拟访问数据的延迟。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: green; font-size: 9pt"&gt;// HACK: Emulate a slow connection to the database.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="color: #2b91af; font-size: 9pt"&gt;Thread&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;.Sleep(1000);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;现在运行范例程序，发现在浏览照片时，非常缓慢，即使你之前已经浏览过相应的照片。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="602" height="520" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/caching/caching_1_2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;在EmployeeService&lt;/b&gt;&lt;b&gt;类实现缓存&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;1. 选择EmployeeBrowser项目，添加对如下程序集的引用。&lt;/div&gt;
&lt;div&gt;Microsoft.Practices.EnterpriseLibrary.Caching.dll&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 打开EmployeeService.cs文件，在代码中添加对Caching命名空间的引用。&lt;/div&gt;
&lt;div&gt;using Microsoft.Practices.EnterpriseLibrary.Caching;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 对GetEmployeePhoto方法添加如下代码。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Bitmap&lt;/span&gt; GetEmployeePhoto(&lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt; employeeId)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;byte&lt;/span&gt;[] photoData = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Attempt to retrieve from cache&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;ICacheManager&lt;/span&gt; cache = &lt;span style="color: #2b91af"&gt;CacheFactory&lt;/span&gt;.GetCacheManager();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            photoData = (&lt;span style="color: blue"&gt;byte&lt;/span&gt;[])cache[employeeId.ToString()];&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Retrieve from dataProvider if not in Cache&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (photoData == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;EmployeeDataProvider&lt;/span&gt; dataProvider = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;EmployeeDataProvider&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                photoData = dataProvider.GetEmployeePhotoData(employeeId);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                cache.Add(employeeId.ToString(), photoData);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// No data found.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (photoData == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Convert bytes to Bitmap&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt; ms = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt;(photoData))&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Bitmap&lt;/span&gt;(ms);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;仔细对比代码，仅仅新增了caching相关的代码机制。上述方法使用了工厂模式（Factory Pattern），和其他的Enterprise Library 的Application Block一样，创建一个新的CacheManager实例。缓存Cache可以完全在内存中，或者依托在物理存储空间，这由配置来决定。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 添加如下的代码到ClearCache方法中，允许窗体请求服务获取新的数据。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; ClearCache()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;ICacheManager&lt;/span&gt; cache = &lt;span style="color: #2b91af"&gt;CacheFactory&lt;/span&gt;.GetCacheManager();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            cache.Flush();&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;上述方法将从Cache中删除所有数据。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;应用程序配置文件&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;1. 使用Enterprise Library的配置文件编辑工具，打开应用程序中app.config配置文件，添加新的Caching Application Block配置，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="681" height="329" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/caching/caching_1_3.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 选择Caching Application Block | Cache Managers | Cache Manager 节点，在属性窗口中，可以看到一些可调整的属性设置，用来调整缓存的性能。这里保留这些设置不变，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="660" height="299" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/caching/caching_1_4.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;保存配置文件，现在配置文件中包含有缓存配置设置。可以注意到后台存储设置为Null Storage，也就是，缓存信息将保留在内存中。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;现在运行范例程序，发现浏览员工信息的性能将发生很大变化。在第一次浏览员工信息时，因为需要从数据库中检索图片信息，因此比较缓慢，但再次访问相同员工的信息时，因为缓存中已经有数据，直接从缓存中获取信息，性能有显著改善。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;&lt;font color="#0000ff"&gt;http://www.entlib.com&lt;/font&gt;&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Caching Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Caching Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/217.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Unity Application Block 学习手册（最新版） Part 4</title><link>http://blog.entlib.com/entlibforum/archive/2009/09/23/enterprise-library-unity-application-block-part-4.aspx</link><pubDate>Tue, 22 Sep 2009 22:44:13 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/09/23/enterprise-library-unity-application-block-part-4.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/215.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/215.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/09/23/enterprise-library-unity-application-block-part-4.aspx#comment</comments><slash:comments>2</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/215.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Unity Application Block 学习手册（最新版） Part 4</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Unity Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 4&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文介绍Enterprise Library – Unity Application Block依赖注入模块的一些基本概念和使用方法。本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib Documentation编译提供，欢迎交流。&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;使用Unity&lt;/b&gt;&lt;b&gt;，最基本步骤有三步：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;1. 建立容器；2. 将接口与类的映射注册到容器中；3. 从容器中解析出正确的对象。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Unity容器使用类型或者名称来识别注册或者类型映射，类型一般为接口或者一个类（通常为基类），实体类实现接口或者继承基类。Unity容器通过调用Resolve或者ResolveAll方法，返回正确的对象类型。当同一个类型有多个映射时，可以通过不同的名称来区分这些映射，同时通过代码指定使用哪一个映射。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;“依赖注入”，一个实体依赖另一个实体，但在早期不体现这种依赖关系，而是把这种依赖关系提取出来，在后期注入回去。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="576" height="360" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/unity/dependency_injection.jpg" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面介绍如何使用依赖注入映射类型和映射。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;接口类型作为依赖识别符（Interface Types as Dependency Identifiers&lt;/b&gt;&lt;b&gt;）&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;作为一个示例，如下代码使用RegisterType和Resolve方法，传入一个接口类型名称，接口命名为IMyService，并指定容器返回一个CustomerService类的实例（该类实现了IMyService接口）。其中，IMyService类型为注册类型，请求IMyService类型将返回CustomerService对象实例。代码使用容器方法的泛型重载。&lt;/div&gt;
&lt;div&gt;IUnityContainer myContainer = new UnityContainer();&lt;/div&gt;
&lt;div&gt;myContainer.RegisterType&amp;lt;IMyService, CustomerService&amp;gt;();&lt;/div&gt;
&lt;div&gt;IMyService myServiceInstance = myContainer.Resolve&amp;lt;IMyService&amp;gt;();&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;此外，你也可以使用该方法的非泛型重载，如下代码获得相同结果。&lt;/div&gt;
&lt;div&gt;IUnityContainer myContainer = new UnityContainer();&lt;/div&gt;
&lt;div&gt;myContainer.RegisterType(typeof(IMyService), typeof(CustomerService));&lt;/div&gt;
&lt;div&gt;IMyService myServiceInstance = (IMyService)myContainer.Resolve(typeof(IMyService));&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;组合依赖识别符和注册名称（Combining Dependency Identifiers and Registration Names&lt;/b&gt;&lt;b&gt;）&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;如果相同的类型需要注册多次，可以指定不同的名称来区分每一个映射。接着通过制定名称和已注册的类型来获取合适的实例。下面的代码演示了如何为同一个接口类注册两次映射，然后Unity容器根据传入给Resolve方法的类型和名称，返回恰当的对象类型。&lt;/div&gt;
&lt;div&gt;// Create container and register types&lt;/div&gt;
&lt;div&gt;IUnityContainer myContainer = new UnityContainer();&lt;/div&gt;
&lt;div&gt;myContainer.RegisterType&amp;lt;IMyService, DataService&amp;gt;("Data");&lt;/div&gt;
&lt;div&gt;myContainer.RegisterType&amp;lt;IMyService, LoggingService&amp;gt;("Logging");&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;// Retrieve an instance of each type&lt;/div&gt;
&lt;div&gt;IMyService myDataService = myContainer.Resolve&amp;lt;IMyService&amp;gt;("Data");&lt;/div&gt;
&lt;div&gt;IMyService myLoggingService = myContainer.Resolve&amp;lt;IMyService&amp;gt;("Logging");&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;已存在对象实例的依赖识别符和BuildUp&lt;/b&gt;&lt;b&gt;方法（Dependency Identifier for Existing Objects and the BuildUp Method&lt;/b&gt;&lt;b&gt;）&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Unity 容器提供了RegisterInstance 方法，允许注册依赖注入映射 – 返回对单一已存在对象实例的引用。这一方法接收一个类型参数（对象接口或类型）和一个已存在的对象实例。当然，如果对同一类型有多个注册，还需要提供不同的命名进行区分。&lt;/div&gt;
&lt;div&gt;下面的代码演示如何使用RegisterInstance 方法注册实现了IMyService接口的、已存在的对象实例。下面的代码同时使用了泛型和非泛型的容器方法。&lt;/div&gt;
&lt;div&gt;DataService myDataService = new DataService();&lt;/div&gt;
&lt;div&gt;EmailService myEmailService = new EmailService();&lt;/div&gt;
&lt;div&gt;LoggingService myLoggingService = new LoggingService();&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;span style="color: #00b050"&gt;// Create container and register existing object instance&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;IUnityContainer myContainer = new UnityContainer();&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;myContainer.RegisterInstance&amp;lt;IMyService&amp;gt;(myDataService);&lt;/div&gt;
&lt;div&gt;myContainer.RegisterInstance&amp;lt;IMyService&amp;gt;("Email", myEmailService);&lt;/div&gt;
&lt;div&gt;myContainer.RegisterInstance(typeof(IMyService), "Logging", myLoggingService);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;span style="color: #00b050"&gt;// Retrieve an instance of each type&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;IMyService theDataService = myContainer.Resolve&amp;lt;IMyService&amp;gt;();&lt;/div&gt;
&lt;div&gt;IMyService theEmailService = myContainer.Resolve&amp;lt;IMyService&amp;gt;("Email");&lt;/div&gt;
&lt;div&gt;IMyService theLoggingService&lt;/div&gt;
&lt;div&gt; = (IMyService)myContainer.Resolve(typeof(IMyService), "Logging");&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;BuildUp方法一个接口或对象类型做法注册标识符，还接收一个已存在对象，并及时应用依赖注入机制。下面的代码演示如何使用BuildUp 方法，为已存在对象实例myDataService和myLoggingService应用依赖注入，这些对象实例实现了IMyService 接口。下面的演示同时使用了Unity容器的泛型和非泛型方法。&lt;/div&gt;
&lt;div&gt;IMyService myDataService = new DataService();&lt;/div&gt;
&lt;div&gt;IMyService myLoggingService = new LoggingService();&lt;/div&gt;
&lt;div&gt;IMyService builtupDataService = myContainer.BuildUp&amp;lt;IMyService&amp;gt;( myDataService);&lt;/div&gt;
&lt;div&gt;IMyService builtupLoggingService&lt;/div&gt;
&lt;div&gt;  = (IMyService)myContainer.BuildUp(typeof(IMyService), myLoggingService);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;通过依赖标识符检索所有已注册类型（Resolving a List of All Registered Types by Dependency Identifiers&lt;/b&gt;&lt;b&gt;）&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;可以通过使用容器的ResolveAll 方法，返回指定类型的所有注册对象列表。该方法接收接口或者类型参数，返回IEnumerable对象实例，包含了所有该类型已注册对象的引用（不含默认映射）。ResolveAll方法返回的列表中仅仅包含命名的实例注册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面的代码演示如何检索指定注册类型的所有已注册类型。&lt;/div&gt;
&lt;div&gt;&lt;span style="color: #00b050"&gt;// Create container and register types using a name for each one&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;IUnityContainer myContainer = new UnityContainer();&lt;/div&gt;
&lt;div&gt;myContainer.RegisterType&amp;lt;IMyService, DefaultService&amp;gt;();&lt;/div&gt;
&lt;div&gt;myContainer.RegisterType&amp;lt;IMyService, DataService&amp;gt;("Data");&lt;/div&gt;
&lt;div&gt;myContainer.RegisterType&amp;lt;IMyService, LoggingService&amp;gt;("Logging");&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;span style="color: #00b050"&gt;// Retrieve a list of non-default types registered for IMyService&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;// List will only contain the types DataService and LoggingService&lt;/div&gt;
&lt;div&gt;IEnumerable&amp;lt;IMyService&amp;gt; serviceList = myContainer.ResolveAll&amp;lt;IMyService&amp;gt;();&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;需要注意的是，如果你希望使用ResolveAll方法返回所有映射的类型，必须在注册类型映射时，同时传入注册类型和一个名称字符串。也就是，必须使用RegisterType和 RegisterInstance方法的重载，传入一个名称（字符串）和依赖类型。这是Unity 的内置设计，要么使用命名的映射，要么仅仅使用默认的映射。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Unity Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Unity Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/215.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Unity Application Block 学习手册（最新版） Part 3</title><link>http://blog.entlib.com/entlibforum/archive/2009/09/16/enterprise-library-unity-application-block-part-3.aspx</link><pubDate>Tue, 15 Sep 2009 20:41:47 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/09/16/enterprise-library-unity-application-block-part-3.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/213.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/213.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/09/16/enterprise-library-unity-application-block-part-3.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/213.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Unity Application Block 学习手册（最新版） Part 3</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Unity Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 3&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文演示Enterprise Library – Unity Application Block依赖注入模块的使用。本文练习通过应用程序的配置文件来设置Unity container，通过配置文件设置依赖注入和Part 2使用API配置比较相似。事实上，配置设置可以认为是调用API的脚本。使用Unity，最基本步骤有三步：1. 建立容器；2. 将接口与类的映射注册到容器中；3. 从容器中解析出正确的对象。&lt;/div&gt;
&lt;div&gt;本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习三：使用配置文件来设置依赖注入容器（Container&lt;/b&gt;&lt;b&gt;）&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;首先，打开Labs\Lab03\begin\StocksTicker 目录下StocksTicker.sln文件。添加对Microsoft.Practices.Unity.Configuration 和 System.Configuration程序集的引用。.NET Framework内置的System.Configuration程序集用来从应用程序配置文件检索配置信息。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;1. 更新启动代码，使用配置文件来设置container&lt;/div&gt;
&lt;div&gt;（1）打开program.cs文件，添加对如下命名空间的引用。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; System.Configuration;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; Microsoft.Practices.Unity.Configuration;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="652" height="383" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/unity/Unity_3_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;（2）从配置文件中检索Unity 配置节，用来配置container，代替对RegisterType方法的调用，代码如下所示。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;IUnityContainer&lt;/span&gt; container = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;UnityContainer&lt;/span&gt;())&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;b&gt;&lt;span style="color: #2b91af"&gt;UnityConfigurationSection&lt;/span&gt; config&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;                    = (&lt;span style="color: #2b91af"&gt;UnityConfigurationSection&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;ConfigurationManager&lt;/span&gt;.GetSection(&lt;span style="color: #a31515"&gt;"unity"&lt;/span&gt;);&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;if&lt;/span&gt; (config != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    config.Containers.Default.Configure(container);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt; presenter&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    = container.Resolve&amp;lt;&lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;.Run((&lt;span style="color: #2b91af"&gt;Form&lt;/span&gt;)presenter.View);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;ConfigurationManager 用来从配置文件中检索配置信息。上述代码使用unity参数从配置文件中获得UnityConfigurationSection对象，表示默认的container配置。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 更新配置文件包含Container配置信息&lt;/div&gt;
&lt;div&gt;打开app.config文件，在 Visual Studio 编辑器中，添加如下unity 配置节点。(EntLib.com 开源小组主：比较遗憾的是，目前EntLib 附带的编辑器不支持对unity application block的相关属性及配置项进行编辑，因此需要手动编辑配置文件)。&lt;/div&gt;
&lt;div&gt;&amp;lt;configSections&amp;gt;&lt;/div&gt;
&lt;div&gt; ...&lt;/div&gt;
&lt;div&gt; &lt;span style="background: yellow"&gt;&amp;lt;section name="unity"&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;           type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;lt;/configSections&amp;gt;&lt;/div&gt;
&lt;div&gt;其中，section的名称unity只有和前面的代码中指定的名称一致即可。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;继续添加unity节点元素，如下所示。&lt;/div&gt;
&lt;div&gt; &amp;lt;/system.diagnostics&amp;gt;&lt;/div&gt;
&lt;div&gt; &lt;span style="background: yellow"&gt;&amp;lt;unity&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt; &amp;lt;/unity&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;lt;/configuration&amp;gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;节点元素名称必须和前面在configSections中注册的section名称保持一致。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;然后为练习中使用到的类型添加typeAlias元素，如下所示：&lt;/div&gt;
&lt;div&gt;&amp;lt;unity&amp;gt;&lt;/div&gt;
&lt;div&gt; &lt;span style="background: yellow"&gt;&amp;lt;typeAliases&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;typeAlias&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      alias="string"&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      type="System.String, mscorlib" /&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;typeAlias&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      alias="TraceSource"&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      type="System.Diagnostics.TraceSource, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;typeAlias&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      alias="singleton"&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;typeAlias&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      alias="ILogger"&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      type="StocksTicker.Loggers.ILogger, StocksTicker" /&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;typeAlias&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      alias="ConsoleLogger"&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      type="StocksTicker.Loggers.ConsoleLogger, StocksTicker" /&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;typeAlias&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      alias="TraceSourceLogger"&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      type="StocksTicker.Loggers.TraceSourceLogger, StocksTicker" /&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;typeAlias&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      alias="IStockQuoteService"&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      type="StocksTicker.StockQuoteServices.IStockQuoteService, StocksTicker" /&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;typeAlias&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      alias="MoneyCentralStockQuoteService"&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      type="StocksTicker.StockQuoteServices.MoneyCentralStockQuoteService, StocksTicker" /&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;typeAlias&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      alias="IStocksTickerView"&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      type="StocksTicker.UI.IStocksTickerView, StocksTicker" /&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;typeAlias&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      alias="StocksTickerForm"&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      type="StocksTicker.UI.StocksTickerForm, StocksTicker" /&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;typeAlias&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      alias="StocksTickerPresenter"&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      type="StocksTicker.UI.StocksTickerPresenter, StocksTicker" /&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt; &amp;lt;/typeAliases&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;lt;/unity&amp;gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;虽然类型别名（type aliases）不是必须的，但这样使得配置文件更易于阅读。每一个typeAlias元素都包含一个alias，在Unity 配置项中可用来代替具体的类型名称。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;在配置文件中，继续添加containers和container元素，如下所示。&lt;/div&gt;
&lt;div&gt; &amp;lt;/typeAliases&amp;gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt; &lt;span style="background: yellow"&gt;&amp;lt;containers&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;container&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;/container&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt; &amp;lt;/containers&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;lt;/unity&amp;gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;默认的container容器和其他命名的container没有什么不同，除了比较容易地通过配置管理对象的Default 属性获取到配置信息。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;为默认的cotainer添加types元素。&lt;/div&gt;
&lt;div&gt;&amp;lt;containers&amp;gt;&lt;/div&gt;
&lt;div&gt; &amp;lt;container&amp;gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;    &lt;span style="background: yellow"&gt;&amp;lt;types&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;/types&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &amp;lt;/container&amp;gt;&lt;/div&gt;
&lt;div&gt;&amp;lt;/containers&amp;gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;types元素的子节点类似于对RegisterType方法的调用，用来将类型注册到容器中。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面添加type元素，将IStocksTickerView接口映射到StocksTickerForm类：&lt;/div&gt;
&lt;div&gt;&amp;lt;types&amp;gt;&lt;/div&gt;
&lt;div&gt; &lt;span style="background: yellow"&gt;&amp;lt;type type="IStocksTickerView" mapTo="StocksTickerForm"/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;lt;/types&amp;gt;&lt;/div&gt;
&lt;div&gt;注：上面使用了类型名称的别名，实际的类型名称也可以在这里使用。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;继续添加type元素，映射IStockQuoteService接口到MoneyCentralStockQuoteService类，且子元素typeConfig 配置注入Logger属性。&lt;/div&gt;
&lt;div&gt;&amp;lt;types&amp;gt;&lt;/div&gt;
&lt;div&gt; &amp;lt;type type="IStocksTickerView" mapTo="StocksTickerForm"/&amp;gt;&lt;/div&gt;
&lt;div&gt; &lt;span style="background: yellow"&gt;&amp;lt;type type="IStockQuoteService" mapTo="MoneyCentralStockQuoteService"&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;typeConfig&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      &amp;lt;property name="Logger" propertyType="ILogger"/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;/typeConfig&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt; &amp;lt;/type&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;lt;/types&amp;gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;添加添加type元素，映射ILogger接口到ConsoleLogger类：&lt;/div&gt;
&lt;div&gt;&amp;lt;types&amp;gt;&lt;/div&gt;
&lt;div&gt; &amp;lt;type type="IStocksTickerView" mapTo="StocksTickerForm"/&amp;gt;&lt;/div&gt;
&lt;div&gt; &amp;lt;type type="IStockQuoteService" mapTo="MoneyCentralStockQuoteService"&amp;gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;    &amp;lt;typeConfig&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;      &amp;lt;property name="Logger" propertyType="ILogger"/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;    &amp;lt;/typeConfig&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &amp;lt;/type&amp;gt;&lt;/div&gt;
&lt;div&gt; &lt;span style="background: yellow"&gt;&amp;lt;type type="ILogger" mapTo="ConsoleLogger"/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;lt;/types&amp;gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面稍有点复杂，添加type元素映射ILogger接口到TraceSourceLogger类，命名为UI。并带有一个子元素typeConfig 表示使用单一字符串参数的构造函数来创建对象实例，定义value元素，传入UI字符串参数。另外，子元素lifetime 通过singleton别名表示使用ContainerControlledLifetimeManager。&lt;/div&gt;
&lt;div&gt;&amp;lt;types&amp;gt;&lt;/div&gt;
&lt;div&gt; &amp;lt;type type="IStocksTickerView" mapTo="StocksTickerForm"/&amp;gt;&lt;/div&gt;
&lt;div&gt; &amp;lt;type type="IStockQuoteService" mapTo="MoneyCentralStockQuoteService"&amp;gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;    ...&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &amp;lt;/type&amp;gt;&lt;/div&gt;
&lt;div&gt; &amp;lt;type type="ILogger" mapTo="ConsoleLogger"/&amp;gt;&lt;/div&gt;
&lt;div&gt; &lt;span style="background: yellow"&gt;&amp;lt;type name="UI" type="ILogger" mapTo="TraceSourceLogger"&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;lifetime type="singleton"/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;typeConfig&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      &amp;lt;constructor&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;        &amp;lt;param name="sourceName" parameterType="string"&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;          &amp;lt;value value="UI"/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;        &amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      &amp;lt;/constructor&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;/typeConfig&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt; &amp;lt;/type&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;lt;/types&amp;gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;constructor元素和代码中的InjectionConstructor类一样。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;最后添加为StocksTickerPresenter类添加type元素，并包括一个子元素typeConfig，配置注入Logger属性，且注入的关键字包括ILogger接口以及名称UI（使用dependency 元素指定名称为UI）。&lt;/div&gt;
&lt;div&gt;&amp;lt;types&amp;gt;&lt;/div&gt;
&lt;div&gt; &amp;lt;type type="IStocksTickerView" mapTo="StocksTickerForm"/&amp;gt;&lt;/div&gt;
&lt;div&gt; &amp;lt;type type="IStockQuoteService" mapTo="MoneyCentralStockQuoteService"&amp;gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;    ...&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &amp;lt;/type&amp;gt;&lt;/div&gt;
&lt;div&gt; &amp;lt;type type="ILogger" mapTo="ConsoleLogger"/&amp;gt;&lt;/div&gt;
&lt;div&gt; &amp;lt;type name="UI" type="ILogger" mapTo="TraceSourceLogger"&amp;gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;    ...&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &amp;lt;/type&amp;gt;&lt;/div&gt;
&lt;div&gt; &lt;span style="background: yellow"&gt;&amp;lt;type type="StocksTickerPresenter"&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;typeConfig&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      &amp;lt;property name="Logger" propertyType="ILogger"&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;        &amp;lt;dependency name="UI"/&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;      &amp;lt;/property&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt;    &amp;lt;/typeConfig&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="background: yellow"&gt; &amp;lt;/type&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;lt;/types&amp;gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下图是Unity配置项的Schema图，还包括每个元素可以设置的属性。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/unity/Unity_3_2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;现在运行范例程序，其运行效果和前面的Part 1 – 2 一致，包括日志功能。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Unity Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Unity Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/213.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Unity Application Block 学习手册（最新版） Part 2</title><link>http://blog.entlib.com/entlibforum/archive/2009/09/15/enterprise-library-unity-application-block-part-2.aspx</link><pubDate>Mon, 14 Sep 2009 19:38:26 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/09/15/enterprise-library-unity-application-block-part-2.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/212.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/212.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/09/15/enterprise-library-unity-application-block-part-2.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/212.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Unity Application Block 学习手册（最新版） Part 2</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Unity Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 2&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文演示Enterprise Library – Unity Application Block依赖注入模块的使用。本文练习配置container在运行时执行依赖注入，不需依赖于在类代码中做attributes标识和设置生命周期管理器。本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习二：通过配置使用Container&lt;/b&gt;&lt;b&gt;容器&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;首先，打开Labs\Lab02\begin\StocksTicker 目录下的StockTicker.sln Solution项目文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;为了提供依赖注入的配置，调用container的RegisterType方法将接收InjectionMember对象，InjectionMember是一个基类，继承类有InjectionProperty和InjectionConstructor，在下面会用到。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;1. 更新container配置，重载默认的注入规则&lt;/div&gt;
&lt;div&gt;（1）更新IStockQuoteService接口调用RegisterType方法的代码，使用InjectionProperty对象注入Logger属性，代码如下所示。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;IUnityContainer&lt;/span&gt; container = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;UnityContainer&lt;/span&gt;())&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                container&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;IStocksTickerView&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;StocksTickerForm&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;IStockQuoteService&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MoneyCentralStockQuoteService&lt;/span&gt;&amp;gt;(&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                        &lt;span style="background: yellow; color: blue"&gt;new&lt;/span&gt;&lt;span style="background: yellow"&gt; &lt;span style="color: #2b91af"&gt;InjectionProperty&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"Logger"&lt;/span&gt;)&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;ILogger&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;ConsoleLogger&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;ILogger&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TraceSourceLogger&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515"&gt;"UI"&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterInstance(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;TraceSource&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"UI"&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;SourceLevels&lt;/span&gt;.All));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt; presenter&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    = container.Resolve&amp;lt;&lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;.Run((&lt;span style="color: #2b91af"&gt;Form&lt;/span&gt;)presenter.View);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;上述代码中配置的InjectionProperty对象表示名称为Logger的属性将被注入container。因为针对该属性没有进一步的配置，因此在获取注入该属性值时，解析该属性的类型ILogger。这和前一节Dependency attribute的使用一样。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;（2）使用RegisterType方法设置StocksTickerPresenter类的注入，代码如下所示。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;IUnityContainer&lt;/span&gt; container = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;UnityContainer&lt;/span&gt;())&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                container&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;IStocksTickerView&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;StocksTickerForm&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;IStockQuoteService&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MoneyCentralStockQuoteService&lt;/span&gt;&amp;gt;(&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                        &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;InjectionProperty&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"Logger"&lt;/span&gt;))&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;ILogger&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;ConsoleLogger&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;ILogger&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TraceSourceLogger&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515"&gt;"UI"&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterInstance(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;TraceSource&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"UI"&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;SourceLevels&lt;/span&gt;.All))&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .&lt;span style="background: yellow"&gt;RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt;&amp;gt;(&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="background: yellow; font-size: 9pt"&gt;                        &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;InjectionProperty&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"Logger"&lt;/span&gt;, &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ResolvedParameter&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;ILogger&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515"&gt;"UI"&lt;/span&gt;)))&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt; presenter&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    = container.Resolve&amp;lt;&lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;.Run((&lt;span style="color: #2b91af"&gt;Form&lt;/span&gt;)presenter.View);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;上述代码中，RegisterType方法没有用来操作类型映射，而仅仅用来注入Logger属性，正因为如此，仅有一个泛型类型的参数。此外，InjectionProperty还传入一个ResolvedParameter对象，该参数表示解析的对象实例名称（前面的示例代码不需要，因此省略了）。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;这些配置已经足够成功运行范例程序了。InjectionConstructor attribute 触发TraceSourceLogger对象的创建，并注入到已注册的TraceSource实例。然而，在很多情况下，你不能够应用InjectionConstructor attribute或者你希望重载attribute和注入不同的对象。下一步，介绍如何使用RegisterType方法重载默认对象创建规则，使用不同的构造器来创建TraceSourceLogger 对象。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;（3）更新ILogger 接口的RegisterType调用方法，使用UI名称来注入对仅含有有一个字符串参数的构造器调用，代码如下所示。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;IUnityContainer&lt;/span&gt; container = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;UnityContainer&lt;/span&gt;())&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                container&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;IStocksTickerView&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;StocksTickerForm&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;IStockQuoteService&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MoneyCentralStockQuoteService&lt;/span&gt;&amp;gt;(&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                        &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;InjectionProperty&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"Logger"&lt;/span&gt;))&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;ILogger&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;ConsoleLogger&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .&lt;span style="background: yellow"&gt;RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;ILogger&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TraceSourceLogger&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515"&gt;"UI"&lt;/span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left; text-indent: 21pt; margin: 0cm 0cm 0pt 84pt" align="left"&gt;&lt;span style="background: yellow; color: blue; font-size: 9pt"&gt;new&lt;/span&gt;&lt;span style="background: yellow; font-size: 9pt"&gt; &lt;span style="color: #2b91af"&gt;InjectionConstructor&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"UI"&lt;/span&gt;))&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterInstance(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;TraceSource&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"UI"&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;SourceLevels&lt;/span&gt;.All))&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt;&amp;gt;(&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                        &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;InjectionProperty&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"Logger"&lt;/span&gt;, &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ResolvedParameter&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;ILogger&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515"&gt;"UI"&lt;/span&gt;)));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt; presenter&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    = container.Resolve&amp;lt;&lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;.Run((&lt;span style="color: #2b91af"&gt;Form&lt;/span&gt;)presenter.View);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;InjectionConstructor 表明根据参数来决定调用哪一个构造函数。上述代码中，传入 UI 字符串，将调用仅仅有一个字符串参数的构造函数，并传入 UI 作为其参数，代替标识有InjectionConstructor attribute的构造函数。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;删除对RegisterInstance的调用，因为这段代码已经没有必要了。&lt;/div&gt;
&lt;div&gt;.RegisterInstance(new TraceSource("UI", SourceLevels.All)&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 运行范例程序&lt;/div&gt;
&lt;div&gt;现在运行范例程序，应该和之前的运行效果一样，但是现在不需要在源代码中添加一些额外的attributes。除了在TraceSourceLogger类的构造函数中还保留了InjectionConstructor attribute，其目的是说明了如何使用配置来覆盖attribute的标识。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;使用RegisterType方法配置注入提供了一定的灵活性，这是使用attributes所没有的，然而，它也需要为container指定每一个注入。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 使用生命周期管理器（Lifetime manager）&lt;/div&gt;
&lt;div&gt;Container使用lifetime manager有2个目的：&lt;/div&gt;
&lt;div&gt;（1）在特定的上下文，确保解析一个特定的对象时总是返回相同的实例。&lt;/div&gt;
&lt;div&gt;（2）合理释放解析的对象。&lt;/div&gt;
&lt;div&gt;下面的练习中，内置的ContainerControlledLifetimeManager将用来释放TraceSourceLogger对象。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;更新TraceSourceLogger&lt;/b&gt;&lt;b&gt;类实现IDisposable&lt;/b&gt;&lt;b&gt;接口&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;目前实现的TraceSourceLogger类在每一个消息记录日志后，都需要调用flush方法，并且不会关闭。在本练习中，该类将更新为实现IDisposable接口，正确关闭TraceSource。&lt;/div&gt;
&lt;div&gt;（1）打开Loggers\TraceSourceLogger.cs文件&lt;/div&gt;
&lt;div&gt;（2）添加TraceSourceLogger类实现IDisposable接口，如下所示。&lt;/div&gt;
&lt;div&gt;（3）删除Log方法中调用Flush方法的代码。&lt;/div&gt;
&lt;div&gt;public void Log(string message, TraceEventType eventType)&lt;/div&gt;
&lt;div&gt;{&lt;/div&gt;
&lt;div&gt;&lt;span&gt;    this.traceSource.TraceEvent(eventType, 0, message);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;    &lt;span style="background: yellow"&gt;// this.traceSource.Flush(); --- &lt;/span&gt;&lt;/span&gt;&lt;span style="background: yellow"&gt;删除这行代码&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;}&lt;/div&gt;
&lt;div&gt;（4）添加实现IDisposable接口的Dispose方法，代码如下所示。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Dispose()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: blue"&gt;this&lt;/span&gt;.traceSource != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;this&lt;/span&gt;.traceSource.TraceInformation(&lt;span style="color: #a31515"&gt;"Shutting down logger"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;this&lt;/span&gt;.traceSource.Close();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;this&lt;/span&gt;.traceSource = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;上述代码记录shutting down消息，然后关闭trace source对象。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;更新container&lt;/b&gt;&lt;b&gt;对TraceSourceLogger&lt;/b&gt;&lt;b&gt;类配置调用，使用Lifetime manager&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;更新对UI - ILogger接口的RegisterType调用方法，传入一个新的ContainerControlledLifetimeManager对象，代码如下所示。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;IUnityContainer&lt;/span&gt; container = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;UnityContainer&lt;/span&gt;())&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                container&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;IStocksTickerView&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;StocksTickerForm&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;IStockQuoteService&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MoneyCentralStockQuoteService&lt;/span&gt;&amp;gt;(&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                        &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;InjectionProperty&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"Logger"&lt;/span&gt;))&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;ILogger&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;ConsoleLogger&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="background: yellow"&gt;.RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;ILogger&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TraceSourceLogger&lt;/span&gt;&amp;gt;(&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="background: yellow; font-size: 9pt"&gt;                        &lt;span style="color: #a31515"&gt;"UI"&lt;/span&gt;, &lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="background: yellow; font-size: 9pt"&gt;                        &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ContainerControlledLifetimeManager&lt;/span&gt;(),&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="background: yellow; font-size: 9pt"&gt;                        &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;InjectionConstructor&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"UI"&lt;/span&gt;))&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt;&amp;gt;(&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                        &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;InjectionProperty&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"Logger"&lt;/span&gt;, &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ResolvedParameter&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;ILogger&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515"&gt;"UI"&lt;/span&gt;)));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt; presenter&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    = container.Resolve&amp;lt;&lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;.Run((&lt;span style="color: #2b91af"&gt;Form&lt;/span&gt;)presenter.View);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;lifetime manager是RegisterType方法的一个可选参数。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;再次运行范例程序，按照前面的操作，输入GM/MSFT等等股票代码，最后关闭主窗口。接着，我们打开ui.log文件（在StocksTicker\bin\Debug目录），会发现在该文件的最后两行，有类似如下的记录。&lt;/div&gt;
&lt;div&gt;UI Information: 0 : Shutting down logger&lt;/div&gt;
&lt;div&gt;&lt;span&gt;    DateTime=2009-02-11T19:02:07.8990000ZZ&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Unity Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Unity Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/212.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Unity Application Block 学习手册（最新版） Part 1</title><link>http://blog.entlib.com/entlibforum/archive/2009/09/14/enterprise-library-unity-application-block-part-1.aspx</link><pubDate>Sun, 13 Sep 2009 19:27:22 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/09/14/enterprise-library-unity-application-block-part-1.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/211.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/211.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/09/14/enterprise-library-unity-application-block-part-1.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/211.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Unity Application Block 学习手册（最新版） Part 1</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Unity Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 1&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文演示Enterprise Library – Unity Application Block依赖注入模块的使用。Unity是微软Pattern &amp;amp; Practices团队设计和开发的一个轻量级的、可扩展的依赖注入（Dependency Injection）容器，提供了构造器、属性和方法调用的注入。&lt;/div&gt;
&lt;div&gt;（1）简化了对象建立，特别是对于层次化的对象结构和依赖，简化了代码。&lt;/div&gt;
&lt;div&gt;（2）支持需求的抽象；允许开发者在运行时或者配置文件中指定依赖，简化了软件开发中所关注问题的管理。&lt;/div&gt;
&lt;div&gt;（3）通过使用容器延缓组件的配置，提高了灵活性。&lt;/div&gt;
&lt;div&gt;（4）具有服务定位功能，使得客户端可以对容器进行存储或缓存。这个特性在ASP.NET网站中特别实用，开发者可以将整个容器存储在Session或Application中。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文练习使用Unity Container创建应用程序对象，并连接在一起。将调用类的构造函数和设置属性值常用方法替换为调用正确配置的Unity Container。本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习一：使用Unity Container&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;首先，打开Labs\Lab01\begin\StocksTicker 目录下的StockTicker.sln Solution项目文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;运行范例程序，在应用程序界面中，输入股票代码，如GM，然后点击Subscribe按钮，并且选择Refresh复选框，在窗口中将显示所订阅股票代码的最新信息，并且在每次接收到股票信息，刷新界面。如下图所示：&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="690" height="464" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/unity/Unity_1_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;应用程序的默认配置是从MoneyCentralRemote获取股票信息，该站点提供在线的、实时的股票市场数据。Console界面显示获取更新股票信息的日志，ui.log文件（在StocksTicker\bin\Debug目录下）在包含了用户界面的操作信息。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;1. 分析范例程序&lt;/div&gt;
&lt;div&gt;范例程序基于Model-View-Presenter(MVP)模式创建，关于MVP的更新信息，可以参考MSDN文章。下图显示了范例程序涉及到的类及其相互关系。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="581" height="383" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/unity/Unity_1_2.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;StocksTickerForm 实现了用户界面，IStockQuoteService 定义了检索当前股票价格的服务接口，MoneyCentralStockService则是该接口的具体实现。ILogger接口及其具体实现用来记录操作日志，最后StocksTickerPresenter 完成显示的角色。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;在启动用户界面之前，静态方法Program.Main() 按顺序创建所有涉及的对象，并相互连接。本文的目标是使用Unity Container代替显式地创建这些对象。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 添加对必要程序集的引用&lt;/div&gt;
&lt;div&gt;对StockTicker项目，添加对Microsoft.Practices.Unity和Microsoft.Practices.ObjectBuilder2程序集的引用。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img width="561" height="446" alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/unity/Unity_1_3.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 更新Startup代码，使用Unity Container&lt;/div&gt;
&lt;div&gt;打开Program.cs文件，添加对Unity 命名空间的引用。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; Microsoft.Practices.Unity;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;使用 UnityContainer对象的Resolve方法创建StocksTickerPresenter对象实例，来代替创建view、presenter、service、logger对象实例的代码，代码如下所示。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Main()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;.EnableVisualStyles();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;.SetCompatibleTextRenderingDefault(&lt;span style="color: blue"&gt;false&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// TODO use a container to create the objects here&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;IUnityContainer&lt;/span&gt; container = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;UnityContainer&lt;/span&gt;())&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt; presenter&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    = container.Resolve&amp;lt;&lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;.Run((&lt;span style="color: #2b91af"&gt;Form&lt;/span&gt;)presenter.View);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;.Run((&lt;span style="color: #2b91af"&gt;Form&lt;/span&gt;)presenter.View);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Unity Container实现了IDisposable接口，因此上述代码利用using语句来释放container对象。&lt;/div&gt;
&lt;div&gt;如果你现在运行范例程序，将抛出ResolutionFailedException异常，这表示试图解析StocksTickerPresenter失败。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面使用REgisterType方法增加container解析接口所需要的类型映射，代码如下所示。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;IUnityContainer&lt;/span&gt; container = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;UnityContainer&lt;/span&gt;())&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                container&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;IStocksTickerView&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;StocksTickerForm&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;IStockQuoteService&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MoneyCentralStockQuoteService&lt;/span&gt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt; presenter&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    = container.Resolve&amp;lt;&lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;.Run((&lt;span style="color: #2b91af"&gt;Form&lt;/span&gt;)presenter.View);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;RegisterType方法是用来设置container的主要机制，可用来映射抽象类型到具体的类，也可以用来重载默认的注入规则和指定生命周期管理器（lifetime manager）。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;上述代码中没有ILogger接口的映射，目前还不是必须的，因为属性还没有注入，除非显式配置。现在，范例程序可以正常运行了，因为涉及的对象都可以由container解析出来，但是没有记录日志，因为logger没有注入到待解析的对象中。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;现在运行范例程序，范例程序可以正常工作，除了日志信息没有出现在console窗口和ui.log文件中。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 使用Attributes控制注入&lt;/div&gt;
&lt;div&gt;Attributes可以用来重载默认的注入规则。在某些情况下，Attributes可以用来选择按照默认规则会忽略的成员注入。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;使用Attributes进行属性注入&lt;/div&gt;
&lt;div&gt;通常情况下，我们希望使用container设置属性，此外，通过构造器传入依赖。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;为MoneyCentralStockQuoteService类的Logger属性设置注入&lt;/div&gt;
&lt;div&gt;（1）打开StockQuoteServices\MoneyCentralStockQuoteService.cs文件&lt;/div&gt;
&lt;div&gt;（2）添加对Unity命名空间的引用&lt;/div&gt;
&lt;div&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; Microsoft.Practices.Unity;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;（3）为Logger属性添加Dependency attribute，代码如下所示。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ILogger&lt;/span&gt; logger;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;Dependency&lt;/span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ILogger&lt;/span&gt; Logger&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; logger; }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;set&lt;/span&gt; { logger = &lt;span style="color: blue"&gt;value&lt;/span&gt;; }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Dependency attribute 表示该属性类型应该注入，在container中解析类型为ILogger。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;（4）添加ILogger类型注册，实现ILogger接口解析&lt;/div&gt;
&lt;div&gt;打开Program.cs文件，使用container类的RegisterType方法，实现ILogger接口到ConsoleLogger类的映射，代码如下所示。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;IUnityContainer&lt;/span&gt; container = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;UnityContainer&lt;/span&gt;())&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                container&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;IStocksTickerView&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;StocksTickerForm&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;IStockQuoteService&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MoneyCentralStockQuoteService&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;ILogger&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;ConsoleLogger&lt;/span&gt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt; presenter&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    = container.Resolve&amp;lt;&lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;.Run((&lt;span style="color: #2b91af"&gt;Form&lt;/span&gt;)presenter.View);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;5. 运行范例程序&lt;/div&gt;
&lt;div&gt;现在运行范例程序，服务调用的操作日志将记录到console窗口，但是用户界面的操作则没有记录到console窗口，因为presenter类的Logger属性仍就没有注入。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;设置注入StocksTickerPresenter类的Logger属性&lt;/div&gt;
&lt;div&gt;与前面的操作一样，对presenter类同样适用Dependency attribute，然后因为注入一个不同的logger实例，Unity container支持多次注册相同的类型，但每一次有不同的名称。当解析依赖时，根据指定的不同名称，返回不同的实例。&lt;/div&gt;
&lt;div&gt;（1）打开UI\ StocksTickerPresenter.cs文件，添加对Unity命名空间的引用。&lt;/div&gt;
&lt;div&gt;（2）对Logger属性添加Dependency attribute，命名为UI，代码如下所示。&lt;/div&gt;
&lt;div&gt;（3）使用UI名称添加类型注册，解析ILogger接口。&lt;/div&gt;
&lt;div&gt;打开Program.cs 文件，使用RegisterType方法映射ILogger接口到TraceSourceLogger类，传入UI名称，代码如下所示。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;IUnityContainer&lt;/span&gt; container = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;UnityContainer&lt;/span&gt;())&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                container&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;IStocksTickerView&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;StocksTickerForm&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;IStockQuoteService&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MoneyCentralStockQuoteService&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;ILogger&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;ConsoleLogger&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;ILogger&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TraceSourceLogger&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515"&gt;"UI"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt; presenter&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    = container.Resolve&amp;lt;&lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;.Run((&lt;span style="color: #2b91af"&gt;Form&lt;/span&gt;)presenter.View);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;如果现在运行范例程序，在解析presenter的Logger属性为TraceSourceLogger实例是，将抛出异常。沿着InnerExpceptions链，找到最终的异常信息为InvalidOperationExpceiton - The type TraceSourceLogger has multiple constructors of length 1. Unable to disambiguate。这是因为Unity默认的注入规则不能识别如何构建对象实例，因此container必须显式配置。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;（4）使用InjectionConstructor attribute显式指定创建TraceSourceLogger对象实例使用的构造函数&lt;/div&gt;
&lt;div&gt;打开Loggers\TraceSourceLogger.cs文件，添加对Unity命名空间的引用。&lt;/div&gt;
&lt;div&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; Microsoft.Practices.Unity;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;添加InjectionConstructor attribute到TraceSourceLogger其中之一的构造函数上，该构造函数接收唯一参数TraceSource，代码如下所示。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;InjectionConstructor&lt;/span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; TraceSourceLogger(&lt;span style="color: #2b91af"&gt;TraceSource&lt;/span&gt; traceSource)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;this&lt;/span&gt;.traceSource = traceSource;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;5. 添加实例注册，来解析TraceSource类型&lt;/div&gt;
&lt;div&gt;在上一步指定构造函数，Unity默认的注入规则将使用该构造函数，且解析.NET Framework TraceSource对象实例，并作为参数传入构造函数。因为TraceSource是.NET Framework内置的类，不能添加attrubite，因此将通过代码自行创建对象实例，并提供给container。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;（1）打开Program.cs文件，使用RegisterInstance方法，指示当解析TraceSource类时，将返回的对象实例，示例代码如下所示。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;IUnityContainer&lt;/span&gt; container = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;UnityContainer&lt;/span&gt;())&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                container&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;IStocksTickerView&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;StocksTickerForm&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;IStockQuoteService&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MoneyCentralStockQuoteService&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;ILogger&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;ConsoleLogger&lt;/span&gt;&amp;gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterType&amp;lt;&lt;span style="color: #2b91af"&gt;ILogger&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;TraceSourceLogger&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515"&gt;"UI"&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    .RegisterInstance(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;TraceSource&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"UI"&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;SourceLevels&lt;/span&gt;.All));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt; presenter&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    = container.Resolve&amp;lt;&lt;span style="color: #2b91af"&gt;StocksTickerPresenter&lt;/span&gt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;.Run((&lt;span style="color: #2b91af"&gt;Form&lt;/span&gt;)presenter.View);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;现在运行范例程序，可以正常工作了，UI操作日志将记录到ui.log文件中，同时来自service的消息显示在console窗口中。&lt;/div&gt;
&lt;div&gt;Attributes是一个方便的机制来重载或消除歧义container的默认注入规则，但是会导致脆弱的依赖，特别是涉及到Dependency名称，因为这样需要在源代码中进行硬编码。下一节将演示其他可选的机制，将container的设置外部化，不必牵扯到所需创建的对象。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Unity Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Unity Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/211.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Validation Application Block 学习手册（最新版） Part 7</title><link>http://blog.entlib.com/entlibforum/archive/2009/09/12/enterprise-library-validation-handling-application-block-part-7.aspx</link><pubDate>Fri, 11 Sep 2009 00:23:19 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/09/12/enterprise-library-validation-handling-application-block-part-7.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/210.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/210.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/09/12/enterprise-library-validation-handling-application-block-part-7.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/210.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Validation Application Block 学习手册（最新版） Part 7</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Validation Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 7&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文演示Enterprise Library – Validation Application Block 验证管理模块的使用，将Validation Application Block与Windows Form进行集成。直接对控件的值进行验证，而不是对业务对象实例进行验证，这一机制和前面的练习不同。本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习七：Validation Application Block&lt;/b&gt;&lt;b&gt;与Windows Form&lt;/b&gt;&lt;b&gt;集成&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;直接打开\Enterprise Library 4.1 HOL\CS\Validation\Labs\Lab07\Before目录下的ValidationHOL.sln项目文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;1. 添加ValidationProvider到Visual Studio 工具栏中&lt;/div&gt;
&lt;div&gt;打开Mainform.cs文件，在Visual Studio工具栏中，右键点击，并选择Choose Items，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="591" height="425" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_7_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;在弹出的窗口中，点击Browse按钮，导航到EntLib的Lib目录，选择如下程序集：&lt;/div&gt;
&lt;div&gt;Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WinForms.dll&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="680" height="455" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_7_2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;点击 open按钮，选择该程序集。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;在接下来的窗口中，选择ValidationProvider 复选框，如下图所示，点击OK按钮。这样，ValidationProvider 将出现在Tool Box中。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="673" height="489" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_7_3.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 在Windows Form 中添加一个ErrorProvider&lt;/div&gt;
&lt;div&gt;尽管这一步不是必须的，但一般情况下标准的ErrorProvider 控件将与ValidatorProvider一起工作，如用户数据录入无效时，提供反馈信息。&lt;/div&gt;
&lt;div&gt;展开Toolbox工具栏中Components标签，选择ErrorProvider，并拖放到设计界面。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 为Customer字段添加Validation的支持&lt;/div&gt;
&lt;div&gt;在设计界面选中ValidationProvider控件，在属性窗口设置如下属性：&lt;/div&gt;
&lt;div&gt;name = customerValidationProvider&lt;/div&gt;
&lt;div&gt;SourceTypeName = ValidationHOL.BusinessLogic.Customer, ValidationHOL.BusinessLogic&lt;/div&gt;
&lt;div&gt;ErrorProvider = errorProvider1&lt;/div&gt;
&lt;div&gt;如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="650" height="400" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_7_4.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;（2）下面进一步设置FirstName和LastName文本框的相关Validation属性。&lt;/div&gt;
&lt;div&gt;选择FirstName文本框，设置如下属性：&lt;/div&gt;
&lt;div&gt;Performs validation on customerValidationProvider = True&lt;/div&gt;
&lt;div&gt;SourcePropertyName = FirstName&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="496" height="200" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_7_5.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;重复上述操作，选择LastName文本框，设置如下属性：&lt;/div&gt;
&lt;div&gt;Performs validation on customerValidationProvider = True&lt;/div&gt;
&lt;div&gt;SourcePropertyName = LastName&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;选择SSN文本框，设置如下属性：&lt;/div&gt;
&lt;div&gt;Performs validation on customerValidationProvider = True&lt;/div&gt;
&lt;div&gt;SourcePropertyName = SSN&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 为Address字段添加Validation支持&lt;/div&gt;
&lt;div&gt;（1）再次拖拉ValidationProvider控件到设计界面；&lt;/div&gt;
&lt;div&gt;（2）设置该ValidationProvider的如下属性：&lt;/div&gt;
&lt;div&gt;name = addressValidationPRovider&lt;/div&gt;
&lt;div&gt;SourcePropertyName = ValidationHOL.BusinessLogic.Address, ValidationHOL.BusinessLogic&lt;/div&gt;
&lt;div&gt;ErrorProvider = errorProvider1&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="680" height="396" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_7_6.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;进一步设置Street Address、City、Zip Code文本框的属性，如下所示：&lt;/div&gt;
&lt;div&gt;PerformValidation on addressValidationProvider = True&lt;/div&gt;
&lt;div&gt;SourcePropertyName on addressValidationProvider = StreetAddress&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="544" height="180" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_7_7.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;City 文本框：&lt;/div&gt;
&lt;div&gt;PerformValidation on addressValidationProvider = True&lt;/div&gt;
&lt;div&gt;SourcePropertyName on addressValidationProvider = City&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Zip Code文本框：&lt;/div&gt;
&lt;div&gt;PerformValidation on addressValidationProvider = True&lt;/div&gt;
&lt;div&gt;SourcePropertyName on addressValidationProvider = ZipCode&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;State下拉列表框：&lt;/div&gt;
&lt;div&gt;PerformValidation on addressValidationProvider = True&lt;/div&gt;
&lt;div&gt;SourcePropertyName on addressValidationProvider = State&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;5. 运行范例程序，检查validation的运行效果，如下图所示。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="680" height="272" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_7_8.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Validation Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Validation Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/210.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Validation Application Block 学习手册（最新版） Part 6</title><link>http://blog.entlib.com/entlibforum/archive/2009/09/10/enterprise-library-validation-handling-application-block-part-6.aspx</link><pubDate>Wed, 09 Sep 2009 20:35:14 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/09/10/enterprise-library-validation-handling-application-block-part-6.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/209.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/209.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/09/10/enterprise-library-validation-handling-application-block-part-6.aspx#comment</comments><slash:comments>3</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/209.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Validation Application Block 学习手册（最新版） Part 6</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Validation Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 6&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文演示Enterprise Library – Validation Application Block 验证管理模块的使用，练习创建多个Rule Sets在不同场景下使用不同的Validation规则来进行数据验证。本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习六：创建并使用多个Rule Sets&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;下面的操作可以在练习五的基础上继续操作，或者直接打开\Enterprise Library 4.1 HOL\CS\Validation\Labs\Lab06\Before目录下的ValidationHOL.sln项目文件。该Solution包含有两个项目，分别为ValidationHOL.BusinessLogic和ValidationHOL。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;1. 创建和配置一个新的、非默认的Rule Set&lt;/div&gt;
&lt;div&gt;（1）使用EntLib的配置管理工具打开app.config文件，右键点击Customer节点，选择 New | Rule Set，创建一个新的Rule Set，命名为Alternative。&lt;/div&gt;
&lt;div&gt;（2）选择Alternative节点，和上一篇操作一样，这里只添加2个属性，分别为FirstName和LastName。&lt;/div&gt;
&lt;div&gt;设置FirstName的String Length Validator的相关属性：&lt;/div&gt;
&lt;div&gt;LowerBound=1&lt;/div&gt;
&lt;div&gt;LowerBoundType=Inclusive&lt;/div&gt;
&lt;div&gt;UpperBound=20&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;继续设置LastName的DomainValidator的相关属性，选择Domain属性，点击相应的按钮，弹出DomainValue Collection Editor对话框。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="628" height="483" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_6_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;在该对话框中，分别添加EntLib, Smith, Jones, Doe等等四个DomainValue，这样限定该属性必须输入指定的属性值，如下图所示。记得操作完成后，需要保存配置文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="641" height="531" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_6_2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 添加一个CheckBox到UI界面上，用来选择使用哪一个Rule Set&lt;/div&gt;
&lt;div&gt;打开MainForm界面，添加一个新的CheckBox，设置如下属性：&lt;/div&gt;
&lt;div&gt;Name = alternativeValidation&lt;/div&gt;
&lt;div&gt;Text = alternative&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="557" height="317" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_6_3.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 更新MainForm类中的acceptButton_Click方法，由CheckBox决定采用哪一个Rule Set对Customer对象实例进行验证。具体代码如下。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; acceptButton_Click(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Customer&lt;/span&gt; customer = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Customer&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                FirstName = firstNameTextBox.Text,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                LastName = lastNameTextBox.Text,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                SSN = ssnTextBox.Text,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                Address = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Address&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    StreetAddress = streetAddressTextBox.Text,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    City = cityTextBox.Text,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    State = stateComboBox.Text,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    ZipCode = zipCodeTextBox.Text&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            };&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;ValidationResults&lt;/span&gt; results =&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;this&lt;/span&gt;.alternativeValidation.Checked&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    ?&lt;b&gt; &lt;span style="color: #2b91af"&gt;Validation&lt;/span&gt;.Validate(customer, &lt;span style="color: #a31515"&gt;"Alternative"&lt;/span&gt;)&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    :&lt;b&gt; &lt;span style="color: #2b91af"&gt;Validation&lt;/span&gt;.Validate(customer)&lt;/b&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (!results.IsValid)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;StringBuilder&lt;/span&gt; builder = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;StringBuilder&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                builder.AppendLine(&lt;span style="color: #a31515"&gt;"Customer is not valid:"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;ValidationResult&lt;/span&gt; result &lt;span style="color: blue"&gt;in&lt;/span&gt; results)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    builder.AppendLine(&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                        &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            &lt;span style="color: #2b91af"&gt;CultureInfo&lt;/span&gt;.CurrentCulture,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            &lt;span style="color: #a31515"&gt;"{0}: {1}"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            result.Key,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            result.Message));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;MessageBox&lt;/span&gt;.Show(&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: blue"&gt;this&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    builder.ToString(),&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: #a31515"&gt;"Error"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: #2b91af"&gt;MessageBoxButtons&lt;/span&gt;.OK,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: #2b91af"&gt;MessageBoxIcon&lt;/span&gt;.Error);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;MessageBox&lt;/span&gt;.Show(&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;this&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #a31515"&gt;"Processing customer '"&lt;/span&gt; + customer.FirstName + &lt;span style="color: #a31515"&gt;"'"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #a31515"&gt;"Working"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;MessageBoxButtons&lt;/span&gt;.OK,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;MessageBoxIcon&lt;/span&gt;.Information);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 运行范例程序，检查是否使用了不同的Rule Set&lt;/div&gt;
&lt;div&gt;如果不选择CheckBox，将采用上一节定义的Default Rule Set对Customer对象实例进行验证，结果和上一节是一样的。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;如果选择Alternative CheckBox，将采用本节新定义的alternative Rule Set，弹出的消息对话框如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="634" height="364" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_6_4.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Validation Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Validation Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/209.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Validation Application Block 学习手册（最新版） Part 5</title><link>http://blog.entlib.com/entlibforum/archive/2009/09/09/enterprise-library-validation-handling-application-block-part-5.aspx</link><pubDate>Tue, 08 Sep 2009 19:34:48 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/09/09/enterprise-library-validation-handling-application-block-part-5.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/208.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/208.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/09/09/enterprise-library-validation-handling-application-block-part-5.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/208.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Validation Application Block 学习手册（最新版） Part 5</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Validation Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 5&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文演示Enterprise Library – Validation Application Block 验证管理模块的使用，练习使用配置文件，而不是attribute来指定验证规则（validation rules）。本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习五：通过配置文件来指定验证规则&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;下面的操作可以在练习四的基础上继续操作，删除Customer和Address类中validation attributes，或者直接打开\Enterprise Library 4.1 HOL\CS\Validation\Labs\Lab05\Before目录下的ValidationHOL.sln项目文件。该Solution包含有两个项目，分别为ValidationHOL.BusinessLogic和ValidationHOL。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;1. 创建配置文件&lt;/div&gt;
&lt;div&gt;为ValidationHOL项目添加配置文件app.config。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 编译Solution&lt;/div&gt;
&lt;div&gt;编译Solution的目的是后续的一些步骤需要装载应用程序的dll。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 使用EntLib的配置编辑工具，为配置文件添加验证配置（validation configuration）&lt;/div&gt;
&lt;div&gt;首先，为app.config配置文件添加Validation Application Block，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="668" height="314" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_5_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 为Customer类添加Validation配置&lt;/div&gt;
&lt;div&gt;（1）右键点击Validation Application Block节点，选择New | Type，为Customer类型添加一个新的节点，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="567" height="245" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_5_2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;在弹出的Type Selector对话框中，选择Load from File按钮，然后找到上一步编译生成的ValidationHOL.BusinessLogic.dll文件（因为该文件包含有Customer类）。在Filter文本框中，输入Customer，这样可以方便找到ValidationHOL.BusinessLogic.dll中包含的Customer类，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="527" height="365" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_5_3.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;（2）为Customer类型添加一个新的Rule Set，并设置Customer类型的默认Rule Set。&lt;/div&gt;
&lt;div&gt;右键点击Customer节点，添加一个新的Rule Set，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="549" height="241" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_5_4.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;选择Rule Set节点，设置Name属性为Default，如下图所示。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="543" height="315" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_5_5.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;然后点击Customer节点，设置DefaultRule属性为Default，也就是上一步新增的Rule Set，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="629" height="259" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_5_6.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;（3）为Customer类型添加新的节点&lt;/div&gt;
&lt;div&gt;右键点击Default节点，选择New | Choose members，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="547" height="268" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_5_7.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;在弹出的Member Selector对话框中，选择Customer类的所有属性，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="619" height="397" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_5_8.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;（4）右键点击FirstName节点，选择New | String Length Validator，为FirstName属性设置String Length Validator，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="639" height="551" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_5_9.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;选择String Length Validator节点，设置如下属性：&lt;/div&gt;
&lt;div&gt;LowerBound=1&lt;/div&gt;
&lt;div&gt;LowerBoundType=Inclusive&lt;/div&gt;
&lt;div&gt;UpperBound=25&lt;/div&gt;
&lt;div&gt;如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="610" height="357" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_5_10.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;重复上述FirstName的操作，为LastName设置String Length Validator，并设置如下属性：&lt;/div&gt;
&lt;div&gt;LowerBound=1&lt;/div&gt;
&lt;div&gt;LowerBoundType=Inclusive&lt;/div&gt;
&lt;div&gt;UpperBound=25&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;继续为SSN属性设置Regular Expression Validator，并设置如下属性：&lt;/div&gt;
&lt;div&gt;Pattern=^\d\d\d-\d\d-\d\d\d\d$&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;继续为Address属性设置Object Validator，不需要设置任何属性。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;5. 按照为Customer类设置Validation配置的步骤，为Address类设置Validation配置。&lt;/div&gt;
&lt;div&gt;首先添加Address类型，然后添加新的Rule Set，并重命名为Default，设置该Rule Set为Address类型的默认Rule Set。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;有点不同的是为City属性设置And Composite Validator，如下图所示，点击City属性，选择New | And Composite Validator。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="606" height="541" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_5_11.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;然后点击 Add Composite Validator节点，按照前面一致的步骤，添加String Length Validator和Contains Character Validator，并为String Length Validator设置如下属性：&lt;/div&gt;
&lt;div&gt;LowerBound=1&lt;/div&gt;
&lt;div&gt;LowerBoundType=Inclusive&lt;/div&gt;
&lt;div&gt;UpperBound=30&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;为Contains Character Validator设置如下属性：&lt;/div&gt;
&lt;div&gt;CharacterSet=sea&lt;/div&gt;
&lt;div&gt;ContainsCharacters=All&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;继续为State属性设置String Length Validator：&lt;/div&gt;
&lt;div&gt;LowerBound=2&lt;/div&gt;
&lt;div&gt;LowerBoundType=Inclusive&lt;/div&gt;
&lt;div&gt;UpperBound=2&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;为StreetAddress属性设置String Length Validator：&lt;/div&gt;
&lt;div&gt;LowerBound=1&lt;/div&gt;
&lt;div&gt;LowerBoundType=Inclusive&lt;/div&gt;
&lt;div&gt;UpperBound=50&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;为ZipCode属性设置Regular Expression Validator：&lt;/div&gt;
&lt;div&gt;Pattern=^\d{5}$&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;上述操作完成后，配置文件如下图所示，记得要保存配置文件。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="579" height="512" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_5_12.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;6. 运行范例程序，检查配置文件中的Validation 配置是否生效&lt;/div&gt;
&lt;div&gt;运行范例程序，在数据录入窗口中，不输入任何信息，点击Accept按钮，将显示错误验证错误信息，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="658" height="422" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_5_13.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Validation Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Validation Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/208.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Validation Application Block 学习手册（最新版） Part 4</title><link>http://blog.entlib.com/entlibforum/archive/2009/09/08/enterprise-library-validation-handling-application-block-part-4.aspx</link><pubDate>Mon, 07 Sep 2009 19:56:40 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/09/08/enterprise-library-validation-handling-application-block-part-4.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/207.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/207.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/09/08/enterprise-library-validation-handling-application-block-part-4.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/207.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Validation Application Block 学习手册（最新版） Part 4</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Validation Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 4&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文演示Enterprise Library – Validation Application Block 验证管理模块的使用，练习使用定制的资源文件重载默认的验证失败的错误消息模板，也可以使用文本消息模板。本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习四：为验证失败使用定制的消息模板&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;下面的操作可以在练习三的基础上继续操作，或者直接打开\Enterprise Library 4.1 HOL\CS\Validation\Labs\Lab04\Before目录下的ValidationHOL.sln项目文件。该Solution包含有两个项目，分别为ValidationHOL.BusinessLogic和ValidationHOL。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;1. 创建资源文件&lt;/div&gt;
&lt;div&gt;右键点击ValidationHOL.BubsinessLogic 项目，选择Properties，点击Resurces 标签，然后点击Link创建默认的资源文件，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="687" height="380" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_4_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 在资源文件中添加字符串&lt;/div&gt;
&lt;div&gt;在资源文件编辑器中添加如下字符串。&lt;/div&gt;
&lt;div&gt;FirstNameMessage – First Name 必须包含{3}到{5}的字符。&lt;/div&gt;
&lt;div&gt;LastNameMessage – Last Name 必须包含{3}到{5}的字符。&lt;/div&gt;
&lt;div&gt;SSNMessage – 社会安全号 (SSN) 必须符合格式 ###-##-####。&lt;/div&gt;
&lt;div&gt;注：上述字符串中的{3}和{5}表示字符串长度的上下限边界。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="665" height="389" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_4_2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 更新Validation Attribute使用资源文件&lt;/div&gt;
&lt;div&gt;在Customer类中，为成员的Validator Attributes设置MessageTemplateResourceType和MessageTemplateResourceName参数为定制的消息模板。&lt;/div&gt;
&lt;div&gt;（1）首先打开 Customer.cs文件，添加如下Namespace的引用，这样默认的资源类型对该类可用。&lt;/div&gt;
&lt;div&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; ValidationHOL.BusinessLogic.Properties;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;（2）更新Customer类中FirstName, LastName和SSN的Validation Attributes。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Customer&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;StringLengthValidator&lt;/span&gt;(1, 25,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            MessageTemplateResourceType = &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Resources&lt;/span&gt;),&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            MessageTemplateResourceName = &lt;span style="color: #a31515"&gt;"FirstNameMessage"&lt;/span&gt;)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; FirstName { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;StringLengthValidator&lt;/span&gt;(1, 25,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            MessageTemplateResourceType = &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Resources&lt;/span&gt;),&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            MessageTemplateResourceName = &lt;span style="color: #a31515"&gt;"LastNameMessage"&lt;/span&gt;)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; LastName { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;RegexValidator&lt;/span&gt;(&lt;span style="color: #a31515"&gt;@"^\d\d\d-\d\d-\d\d\d\d$"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            MessageTemplateResourceType = &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Resources&lt;/span&gt;),&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            MessageTemplateResourceName = &lt;span style="color: #a31515"&gt;"SSNMessage"&lt;/span&gt;)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; SSN { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;ObjectValidator&lt;/span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Address&lt;/span&gt; Address { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;    }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 检查是否使用资源文件中定义的消息模板覆盖了默认的验证错误消息&lt;/div&gt;
&lt;div&gt;运行范例程序，在数据录入窗口，不录入任何信息，点击Accept按钮，弹出验证错行消息对话框，如下图所示，默认的错误消息已经替换为资源文件中定义的字符串。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="647" height="398" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_4_3.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Validation Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Validation Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/207.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Validation Application Block 学习手册（最新版） Part 3</title><link>http://blog.entlib.com/entlibforum/archive/2009/09/07/enterprise-library-validation-handling-application-block-part-3.aspx</link><pubDate>Sun, 06 Sep 2009 19:20:10 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/09/07/enterprise-library-validation-handling-application-block-part-3.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/206.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/206.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/09/07/enterprise-library-validation-handling-application-block-part-3.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/206.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Validation Application Block 学习手册（最新版） Part 3</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Validation Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 3&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文演示Enterprise Library – Validation Application Block 验证管理模块的使用，练习使用ObjectValidator对嵌入对象进行验证。本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习三：验证嵌入对象&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;下面的操作可以在练习二的基础上继续操作，或者直接打开\Enterprise Library 4.1 HOL\CS\Validation\Labs\Lab03\Before目录下的ValidationHOL.sln项目文件。该Solution包含有两个项目，分别为ValidationHOL.BusinessLogic和ValidationHOL。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;1. 添加[ObjectValidator]特性到Customer类的Address属性上，代码如下所示。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Customer&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;StringLengthValidator&lt;/span&gt;(1, 25)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; FirstName { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;StringLengthValidator&lt;/span&gt;(1, 25)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;       &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; LastName { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;RegexValidator&lt;/span&gt;(&lt;span style="color: #a31515"&gt;@"^\d\d\d-\d\d-\d\d\d\d$"&lt;/span&gt;)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; SSN { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;ObjectValidator&lt;/span&gt;]&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Address&lt;/span&gt; Address { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;    }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 运行范例程序，检查Address类中的相关字段是否按照指定的验证规则进行验证。&lt;/div&gt;
&lt;div&gt;在数据录入界面，不输入任何信息，如下图所示，点击Accept按钮，在弹出的错误消息对话框中，包含了具体的验证失败信息，其中也包含了对Address类中相关字段的验证。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="661" height="447" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_3_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面进一步需要录入Customer类的前3个属性（FirstName，LastName，SSN），看看是否验证通过。如下图所示，现在不能通过validation rules的验证了，因为Address类的相关字段没有通过验证。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="617" height="364" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_3_2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Validation Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Validation Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/206.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Validation Application Block 学习手册（最新版） Part 2</title><link>http://blog.entlib.com/entlibforum/archive/2009/09/07/enterprise-library-validation-handling-application-block-part-2.aspx</link><pubDate>Sun, 06 Sep 2009 19:07:10 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/09/07/enterprise-library-validation-handling-application-block-part-2.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/205.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/205.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/09/07/enterprise-library-validation-handling-application-block-part-2.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/205.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Validation Application Block 学习手册（最新版） Part 2</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Validation Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 2&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文演示Enterprise Library – Validation Application Block 验证管理模块的使用，检查验证操作的返回结果集，从验证失败中获取更多详细的信息。本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习二：遍历验证返回的结果集&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;下面的操作可以在练习一的基础上继续操作，或者直接打开\Enterprise Library 4.1 HOL\CS\Validation\Labs\Lab02\Before目录下的ValidationHOL.sln项目文件。该Solution包含有两个项目，分别为ValidationHOL.BusinessLogic和ValidationHOL。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;在上一节的练习中，仅仅一个错误的消息对话框，包含的信息过于简单。下面从ValidationResult中获取更多的详细信息。ValidationResults结果集中的每一个ValidationResult元素都包含了单一验证规则（Validation Rule）的验证失败信息，这些具体的信息可以显示在错误消息对话框中。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;1. 打开MainForm.cs文件，添加如下命名空间的引用。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; System.Text;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; System.Globalization;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 更新MainForm.cs类中的acceptButton_Click方法，创建一个错误的StringBuilder，包含了所有ValidationResult元素中信息，代码如下。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;private&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; acceptButton_Click(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Customer&lt;/span&gt; customer = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Customer&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                FirstName = firstNameTextBox.Text,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                LastName = lastNameTextBox.Text,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                SSN = ssnTextBox.Text,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                Address = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Address&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    StreetAddress = streetAddressTextBox.Text,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    City = cityTextBox.Text,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    State = stateComboBox.Text,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    ZipCode = zipCodeTextBox.Text&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            };&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;ValidationResults&lt;/span&gt; results = &lt;span style="color: #2b91af"&gt;Validation&lt;/span&gt;.Validate(customer);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (!results.IsValid)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;StringBuilder&lt;/span&gt; builder = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;StringBuilder&lt;/span&gt;();&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;                builder.AppendLine(&lt;span style="color: #a31515"&gt;"Customer is not valid:"&lt;/span&gt;);&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;ValidationResult&lt;/span&gt; result &lt;span style="color: blue"&gt;in&lt;/span&gt; results)&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;                {&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;                    builder.AppendLine(&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;                        &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;                            &lt;span style="color: #2b91af"&gt;CultureInfo&lt;/span&gt;.CurrentCulture,&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;                            &lt;span style="color: #a31515"&gt;"{0}: {1}"&lt;/span&gt;,&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;                            result.Key,&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;                            result.Message));&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;                }&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;MessageBox&lt;/span&gt;.Show(&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: blue"&gt;this&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    builder.ToString(),&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: #a31515"&gt;"Error"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: #2b91af"&gt;MessageBoxButtons&lt;/span&gt;.OK,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: #2b91af"&gt;MessageBoxIcon&lt;/span&gt;.Error);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;MessageBox&lt;/span&gt;.Show(&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;this&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #a31515"&gt;"Processing customer '"&lt;/span&gt; + customer.FirstName + &lt;span style="color: #a31515"&gt;"'"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #a31515"&gt;"Working"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;MessageBoxButtons&lt;/span&gt;.OK,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;MessageBoxIcon&lt;/span&gt;.Information);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;上述代码使用ValidationResult元素的Key和Message属性，构建错误消息字符串。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 运行范例程序，检查是否正确遍历了ValidationResults结果集，且正确显示了错误信息。&lt;/div&gt;
&lt;div&gt;在数据录入界面，不输入任何信息，如下图所示，点击Accept按钮，在弹出的错误消息对话框中，包含了具体的验证失败信息。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="643" height="361" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_2_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;从上图中可以看出，仅仅显示了Customer类相关的错误信息，事实上，只需要录入Customer类的前3个属性（FirstName，LastName，SSN）就可以通过Validation rules的验证了，尽管Address类的相关属性也有validation的特性。这说明了嵌入类的验证不会自动触发，因此需要显式的调用，在下一节练习中介绍如何执行嵌入类的验证操作。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="547" height="320" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_2_2.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Validation Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Validation Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/205.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Validation Application Block 学习手册（最新版） Part 1</title><link>http://blog.entlib.com/entlibforum/archive/2009/09/06/enterprise-library-validation-handling-application-block-part-1.aspx</link><pubDate>Sat, 05 Sep 2009 20:34:29 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/09/06/enterprise-library-validation-handling-application-block-part-1.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/204.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/204.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/09/06/enterprise-library-validation-handling-application-block-part-1.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/204.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Validation Application Block 学习手册（最新版） Part 1</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Validation Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 1&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文演示Enterprise Library – Validation Application Block 验证管理模块的使用。总共有13个练习，前面11个练习在Windows Form应用程序处理用户输入的数据，赋值给Customer和Address业务对象。Validation Application Block用来在处理数据之前，验证创建的业务对象。第12个练习演示如何使用Validation Application Block集成ASP.NET验证特性，验证ASP.NET控件值。在第13个练习中，APS.NET Application 作为Windows Communication Foundation（WCF）服务前端，利用Validation Application Block集成WCF验证特性，在Server端验证服务参数。本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习一：添加验证&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;本文练习对业务对象实施验证操作，和对一个简单的数据录入应用程序使用using 属性指定验证规则（Validation Rule）。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;1. 首先打开\Enterprise Library 4.1 HOL\CS\Validation\Labs\Lab01\Before目录下的ValidationHOL.sln项目文件。该Solution包含有两个项目，分别为ValidationHOL.BusinessLogic和ValidationHOL。&lt;/div&gt;
&lt;div&gt;因为现在还没有对ValidationHOL项目做任何更改，在运行范例程序，点击Accept按钮时，没有执行任何验证操作，应用程序则试图处理无效的数据。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文主要包含如下内容：&lt;/div&gt;
&lt;div&gt;（1）添加验证属性到业务类中；&lt;/div&gt;
&lt;div&gt;（2）对业务对象实例调用验证规则；&lt;/div&gt;
&lt;div&gt;针对特定类型的验证不会自动执行，需要在Client端显式调用。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 为ValidationHOL.BusinessLogic 项目添加Microsoft.Practices.EnterpriseLibrary.Validation.dll 程序集的引用。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;打开ValidationHOL.BusinessLogic 项目中Customer.cs文件，添加对Validation 命名空间的引用。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; Microsoft.Practices.EnterpriseLibrary.Validation.Validators;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 为Customer类的属性添加validation特征。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Customer&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;StringLengthValidator&lt;/span&gt;(1, 25)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; FirstName { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;StringLengthValidator&lt;/span&gt;(1, 25)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; LastName { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;RegexValidator&lt;/span&gt;(&lt;span style="color: #a31515"&gt;@"^\d\d\d-\d\d-\d\d\d\d$"&lt;/span&gt;)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; SSN { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Address&lt;/span&gt; Address { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;    }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 为Address类的属性添加validation特征。&lt;/div&gt;
&lt;div&gt;打开Address.cs文件，添加如下命名空间的引用。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; Microsoft.Practices.EnterpriseLibrary.Validation;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; Microsoft.Practices.EnterpriseLibrary.Validation.Validators;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;进一步修改Address类，如下所示;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Address&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;StringLengthValidator&lt;/span&gt;(1, 50)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; StreetAddress { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;ValidatorComposition&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;CompositionType&lt;/span&gt;.And)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;StringLengthValidator&lt;/span&gt;(1, 30)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;ContainsCharactersValidator&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"sea"&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;ContainsCharacters&lt;/span&gt;.All)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; City { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;StringLengthValidator&lt;/span&gt;(2, 2)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; State { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;RegexValidator&lt;/span&gt;(&lt;span style="color: #a31515"&gt;@"^\d{5}$"&lt;/span&gt;)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; ZipCode { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;    }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;上述代码中，针对City属性定义了多个validation attributes。当针对某一个类的属性定义多个validation attributes时，需要创建一个组合的验证特性（composite validator），设置为多个validation attributes之间是and或or 的关系。当为and时，需要所有的validation attributes验证通过时，才验证通过。如果为or时，则只需要一个validation attribute符合，就验证通过。ContainsCharactersValidator 要求City属性中必须同时包含有s、e、a三个字符。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;5. 下面针对业务对象实例调用验证&lt;/div&gt;
&lt;div&gt;Validation必须通过代码显式调用，除非一些特殊的机制，如Policy Injection Application Block，可以用来截取方法调用。&lt;/div&gt;
&lt;div&gt;调用验证的结果是生成一个ValidationResults实例，该实例表示验证是否成功。如果没有成功，则包含每一个验证规则失败的ValidationResult实例集合。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;（1）为ValidationHOL项目添加对Microsoft.Practices.EnterpriseLibrary.Validation.dll程序集的引用。&lt;/div&gt;
&lt;div&gt;（2）打开MainForm.cs文件，添加如下命名空间的引用。&lt;/div&gt;
&lt;div&gt;using Microsoft.Practices.EnterpriseLibrary.Validation;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;（3）更新MainForm类的acceptButton_Click方法，调用validation，如验证失败，则显示一个错误消息。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面运行范例程序，检查验证规则是否生效。&lt;/div&gt;
&lt;div&gt;首先，文本框不输入任何内容，点击Accept按钮，将弹出一个错误信息窗口，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="550" height="333" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_1_1.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;继续按照验证规则的要求，输入正确的Customer数据，点击Accept按钮，检查是否通过验证规则。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="545" height="319" src="/userfiles/entlibforum/image/EnterpriseLibrary/validation/Validation_1_2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Validation Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Validation Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/204.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Logging Application Block 学习手册（最新版） Part 3</title><link>http://blog.entlib.com/entlibforum/archive/2009/09/05/enterprise-library-logging-handling-application-block-part-3.aspx</link><pubDate>Fri, 04 Sep 2009 00:34:06 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/09/05/enterprise-library-logging-handling-application-block-part-3.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/203.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/203.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/09/05/enterprise-library-logging-handling-application-block-part-3.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/203.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Logging Application Block 学习手册（最新版） Part 3</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Logging Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 3&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文演示Enterprise Library – Logging Application Block 日志管理模块的使用，以及如何创建和使用定制的TraceListener和LogFormatter。本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习三：创建和使用定制的Log Formatter&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;本文练习如何创建一个定制的LogFormatter，并应用到logging应用程序中。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;1. 首先打开\Enterprise Library 4.1 HOL\CS\Logging\exercises\ex03\begin目录下的EnoughPI.sln项目文件，该应用程序用来计算pi值。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;2. &lt;/b&gt;&lt;b&gt;创建定制的Log Formatter&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;选择Formatters\XmlFormatter.cs 文件，添加如下命名空间的引用：&lt;/div&gt;
&lt;div&gt;using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;&lt;/div&gt;
&lt;div&gt;using Microsoft.Practices.EnterpriseLibrary.Logging;&lt;/div&gt;
&lt;div&gt;using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration;&lt;/div&gt;
&lt;div&gt;using Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;添加如下的代码到XmlFormatter类中。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    [&lt;span style="color: #2b91af"&gt;ConfigurationElementType&lt;/span&gt;(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;CustomFormatterData&lt;/span&gt;))]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;XmlFormatter&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;LogFormatter&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;NameValueCollection&lt;/span&gt; Attributes = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; XmlFormatter(&lt;span style="color: #2b91af"&gt;NameValueCollection&lt;/span&gt; attributes)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;this&lt;/span&gt;.Attributes = attributes;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;override&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; Format(&lt;span style="color: #2b91af"&gt;LogEntry&lt;/span&gt; log)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;string&lt;/span&gt; prefix = &lt;span style="color: blue"&gt;this&lt;/span&gt;.Attributes[&lt;span style="color: #a31515"&gt;"prefix"&lt;/span&gt;];&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;string&lt;/span&gt; ns = &lt;span style="color: blue"&gt;this&lt;/span&gt;.Attributes[&lt;span style="color: #a31515"&gt;"namespace"&lt;/span&gt;];&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;StringWriter&lt;/span&gt; s = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;StringWriter&lt;/span&gt;())&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;XmlTextWriter&lt;/span&gt; w = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;XmlTextWriter&lt;/span&gt;(s);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                w.Formatting = &lt;span style="color: #2b91af"&gt;Formatting&lt;/span&gt;.Indented;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                w.Indentation = 2;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                w.WriteStartDocument(&lt;span style="color: blue"&gt;true&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                w.WriteStartElement(prefix, &lt;span style="color: #a31515"&gt;"logEntry"&lt;/span&gt;, ns);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                w.WriteAttributeString(&lt;span style="color: #a31515"&gt;"Priority"&lt;/span&gt;, ns,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    log.Priority.ToString(&lt;span style="color: #2b91af"&gt;CultureInfo&lt;/span&gt;.InvariantCulture));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                w.WriteElementString(&lt;span style="color: #a31515"&gt;"Timestamp"&lt;/span&gt;, ns, log.TimeStampString);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                w.WriteElementString(&lt;span style="color: #a31515"&gt;"Message"&lt;/span&gt;, ns, log.Message);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                w.WriteElementString(&lt;span style="color: #a31515"&gt;"EventId"&lt;/span&gt;, ns,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    log.EventId.ToString(&lt;span style="color: #2b91af"&gt;CultureInfo&lt;/span&gt;.InvariantCulture));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                w.WriteElementString(&lt;span style="color: #a31515"&gt;"Severity"&lt;/span&gt;, ns, log.Severity.ToString());&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                w.WriteElementString(&lt;span style="color: #a31515"&gt;"Title"&lt;/span&gt;, ns, log.Title);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                w.WriteElementString(&lt;span style="color: #a31515"&gt;"Machine"&lt;/span&gt;, ns, log.MachineName);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                w.WriteElementString(&lt;span style="color: #a31515"&gt;"AppDomain"&lt;/span&gt;, ns, log.AppDomainName);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                w.WriteElementString(&lt;span style="color: #a31515"&gt;"ProcessId"&lt;/span&gt;, ns, log.ProcessId);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                w.WriteElementString(&lt;span style="color: #a31515"&gt;"ProcessName"&lt;/span&gt;, ns, log.ProcessName);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                w.WriteElementString(&lt;span style="color: #a31515"&gt;"Win32ThreadId"&lt;/span&gt;, ns, log.Win32ThreadId);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                w.WriteElementString(&lt;span style="color: #a31515"&gt;"ThreadName"&lt;/span&gt;, ns, log.ManagedThreadName);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                w.WriteEndElement();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                w.WriteEndDocument();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt; s.ToString();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;    }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;日志记录将格式化为XML，另外需要传入2个参数，分别为prefix和namespace。&lt;/div&gt;
&lt;div&gt;编译整个项目，确保生成定制的log formatter的DLL文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;3. &lt;/b&gt;&lt;b&gt;应用定制的log formatter&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;使用EntLib的配置管理工具打开app.config配置文件，选择Logging Application Block | Formatters节点，添加一个新的Custom Formatter，并设置如下属性：&lt;/div&gt;
&lt;div&gt;Name = Xml Formatter&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="639" height="361" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_3_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;
选择Type属性，点击相应的按钮，显示Type Selector对话框，如下图所示。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="563" height="370" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_3_2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;选择前一步编译生成的EnoughPI.Logging.dll文件，从EnoughtPI.Logging 程序集中选择XmlFormatter类，然后点击OK按钮。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;然后选择Attributes属性，点击后面的按钮，显示EditableKeyValue Collection Editor对话框，如下图所示。添加如下Key/Value值：&lt;/div&gt;
&lt;div&gt;Key = prefix, Value = x&lt;/div&gt;
&lt;div&gt;Key = namespace, Value = EnoughPI/2.0&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="557" height="375" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_3_3.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;你应该还记得XmlFormatter需要传入2个参数，分别为prefix和namespace，上述操作正是给这两个参数设定参数值。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;然后选择 Logging Application Block | Trace Listeners | Custom TraceListener 节点，设置如下属性：Formatter = Xml Formatter&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="686" height="482" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_3_4.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;保存所有设置，然后再次运行范例程序，日志记录将再次显示在Console窗口，不过这次在窗口中显示的是XML格式。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="690" height="449" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_3_5.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;现在，我们已经完成了创建和应用Custom Log Formatter。&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问Validation Application Block学习手册。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Logging Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/203.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Logging Application Block 学习手册（最新版） Part 2</title><link>http://blog.entlib.com/entlibforum/archive/2009/09/03/enterprise-library-logging-handling-application-block-part-2.aspx</link><pubDate>Wed, 02 Sep 2009 20:00:32 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/09/03/enterprise-library-logging-handling-application-block-part-2.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/202.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/202.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/09/03/enterprise-library-logging-handling-application-block-part-2.aspx#comment</comments><slash:comments>3</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/202.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Logging Application Block 学习手册（最新版） Part 2</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Logging Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 2&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文演示Enterprise Library – Logging Application Block 日志管理模块的使用，以及如何创建和使用定制的TraceListener和LogFormatter。本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习二：创建和使用定制的Trace Listener&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;本文练习如何创建一个定制的Trace Listener，用来传送格式化的日志记录到Console输出。接着将该Trace Listener应用到EnoughPI范例应用程序中，实时监控日志记录。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;1. 首先打开\Enterprise Library 4.1 HOL\CS\Logging\exercises\ex02\begin目录下的EnoughPI.sln项目文件，该应用程序用来计算pi值。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;2. &lt;/b&gt;&lt;b&gt;创建定制的Trace Listener&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;选择EnoughPI.Logging项目，添加对如下DLL的引用：&lt;/div&gt;
&lt;div&gt;Microsoft.Practices.EnterpriseLibrary.Common.dll&lt;/div&gt;
&lt;div&gt;Microsoft.Practices.EnterpriseLibrary.Logging.dll&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;选择TraceListeners\ConsoleTraceListener.cs 文件，添加对如下命名空间的引用：&lt;/div&gt;
&lt;div&gt;using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;&lt;/div&gt;
&lt;div&gt;using Microsoft.Practices.EnterpriseLibrary.Logging;&lt;/div&gt;
&lt;div&gt;using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration;&lt;/div&gt;
&lt;div&gt;using Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;&lt;/div&gt;
&lt;div&gt;using Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;添加如下代码到ConsoleTraceListener类中：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    [&lt;span style="color: #2b91af"&gt;ConfigurationElementType&lt;/span&gt;(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;CustomTraceListenerData&lt;/span&gt;))]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ConsoleTraceListener&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;CustomTraceListener&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; ConsoleTraceListener() : &lt;span style="color: blue"&gt;base&lt;/span&gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;override&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; TraceData(&lt;span style="color: #2b91af"&gt;TraceEventCache&lt;/span&gt; eventCache,&lt;span style="color: blue"&gt;string&lt;/span&gt; source, &lt;span style="color: #2b91af"&gt;TraceEventType&lt;/span&gt; eventType, &lt;span style="color: blue"&gt;int&lt;/span&gt; id, &lt;span style="color: blue"&gt;object&lt;/span&gt; data)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (data &lt;span style="color: blue"&gt;is&lt;/span&gt; &lt;span style="color: #2b91af"&gt;LogEntry&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.Formatter != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;this&lt;/span&gt;.WriteLine(&lt;span style="color: blue"&gt;this&lt;/span&gt;.Formatter.Format(data &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;LogEntry&lt;/span&gt;));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;this&lt;/span&gt;.WriteLine(data.ToString());&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;override&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Write(&lt;span style="color: blue"&gt;string&lt;/span&gt; message)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.Write(message);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;override&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; WriteLine(&lt;span style="color: blue"&gt;string&lt;/span&gt; message)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Delimit each message&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine((&lt;span style="color: blue"&gt;string&lt;/span&gt;)&lt;span style="color: blue"&gt;this&lt;/span&gt;.Attributes[&lt;span style="color: #a31515"&gt;"delimiter"&lt;/span&gt;]);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Write formatted message&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(message);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;    }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;CustomTraceListener基类要求重载2个抽象方法：Write 和 WriteLine。如需要格式化消息，则需要重载TraceDate方法。ConsoleTraceListener需要传入参数delimiter，该参数是listener一个配置项。记得要编译一下整个项目，这样可以生成CustomTraceListener的dll文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;3. &lt;/b&gt;&lt;b&gt;应用定制的TraceListener&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;利用EntLib的配置管理工具对app.config进行配置。选择Application Block | Trace Listeners节点，添加一个新的Custom Trace Listener，并设置Formatter = Text Formatter。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="518" height="436" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_2_1.gif" /&gt; &lt;/div&gt;
&lt;div&gt;接着选择Type属性，并点击按钮，弹出Type Selector对话框。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="583" height="615" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_2_2.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;&lt;br /&gt;
在弹出的对话框，点击Load from File按钮，找到EnoughPI.Logging 项目编译输出的文件夹，选择EnoughPI.Logging.dll文件。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="625" height="441" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_2_3.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;&lt;br /&gt;
选择EnoughPI.Logging 程序集中的ConsoleTraceListener类，然后点击OK按钮，如下图所示。&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="604" height="461" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_2_4.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;在属性窗口中，选择Attributes属性，点击相应的按钮，显示EditableKeyValue Collection Editor对话框，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="420" height="300" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_2_5.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;在EditableKeyValue Collection Editor对话框，点击Add按钮，添加如下key/value：&lt;/div&gt;
&lt;div&gt;Key = delimiter&lt;/div&gt;
&lt;div&gt;Value = "---------------------------"&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="589" height="423" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_2_6.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;你应该还记得前面的ConsoleTraceListener代码中需要一个delimiter参数，在打印格式化的消息之前，先打印delimiter参数值。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面选择Logging Application Block | Category Sources | General 节点，添加一个新的Trace Listener引用，并设置ReferencedTraceListener = Custom TraceListener（上一步导入的ConsoleTraceListener）。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="698" height="427" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_2_7.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;现在别忘了保存配置文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 运行范例程序&lt;/div&gt;
&lt;div&gt;运行范例程序，检查Visual Studio中Output窗口的输出，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="518" height="280" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_2_8.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面改变项目的输出方式。选择EnoughPI项目，选择Project | EnoughPI Properties… 菜单项，在Application 选项页面中，设置Output type = Console Application。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="690" height="518" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_2_9.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;再次运行范例程序，日志记录将显示在Console窗口，如下图所示。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="690" height="470" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_2_10.gif" /&gt; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;现在，我们已经完成了创建和应用Custom Trace Listener。&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问下一节内容。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Logging Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/202.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Logging Application Block 学习手册（最新版） Part 1</title><link>http://blog.entlib.com/entlibforum/archive/2009/09/02/enterprise-library-logging-handling-application-block-part-1.aspx</link><pubDate>Tue, 01 Sep 2009 19:44:08 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/09/02/enterprise-library-logging-handling-application-block-part-1.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/201.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/201.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/09/02/enterprise-library-logging-handling-application-block-part-1.aspx#comment</comments><slash:comments>5</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/201.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Logging Application Block 学习手册（最新版） Part 1</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Logging Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 1&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文演示Enterprise Library – Logging Application Block 日志管理模块的使用，以及如何创建和使用定制的TraceListener和LogFormatter。本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习一：为应用程序添加日志记录功能&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;本文练习如何使用Logging Application Block，通过 EntLib 配置工具来配置TraceListener。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;1. 首先打开\Enterprise Library 4.1 HOL\CS\Logging\exercises\ex01\begin目录下的EnoughPI.sln项目文件，该应用程序用来计算pi值。可以直接运行应用程序，如下图所示：&lt;/div&gt;
&lt;div style="text-align: center"&gt; &lt;img alt="" width="308" height="468" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_1_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt;2. 添加记录日志功能&lt;/div&gt;
&lt;div&gt;选择EnoughPI项目，添加对logging dll的引用：&lt;/div&gt;
&lt;div&gt;Microsoft.Practices.EnterpriseLibrary.Logging.dll。&lt;/div&gt;
&lt;div&gt;一般该dll在如下目录（根据安装选择的路径发生变化）：&lt;/div&gt;
&lt;div&gt;C:\Program Files\Microsoft Enterprise Library 4.1 - October 2008\Bin&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;打开Calc\Calculator.cs 代码文件，添加命名空间的引用：&lt;/div&gt;
&lt;div&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; Microsoft.Practices.EnterpriseLibrary.Logging;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;找到Calculator.cs代码文件中OnCalculated方法，添加如下代码：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;protected&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; OnCalculated(&lt;span style="color: #2b91af"&gt;CalculatedEventArgs&lt;/span&gt; args)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;LogEntry&lt;/span&gt; log = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;LogEntry&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            log.Message = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;"Calculated PI to {0} digits"&lt;/span&gt;, args.Digits);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            log.Categories.Add(&lt;span style="color: #2b91af"&gt;Category&lt;/span&gt;.General);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            log.Priority = &lt;span style="color: #2b91af"&gt;Priority&lt;/span&gt;.Normal;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Logger&lt;/span&gt;.Write(log);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt; &lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (Calculated != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                Calculated(&lt;span style="color: blue"&gt;this&lt;/span&gt;, args);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;上述代码创建了一个新的LogEntry对象，设置相关参数值，并使用Logger.Write方法将entry对象写入到一个或多个TraceListener。这里使用到了Constants.cs代码中定义的一些常量，如Category和Priority。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面找到Calculator.cs代码文件中的OnCalculating方法，添加如下log日志代码：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;protected&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; OnCalculating(&lt;span style="color: #2b91af"&gt;CalculatingEventArgs&lt;/span&gt; args)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Logger&lt;/span&gt;.Write(&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;"Calculating next 9 digits from {0}"&lt;/span&gt;, args.StartingAt),&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;Category&lt;/span&gt;.General,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;Priority&lt;/span&gt;.Low&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            );&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt; &lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (Calculating != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                Calculating(&lt;span style="color: blue"&gt;this&lt;/span&gt;, args);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt; &lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (args.Cancel == &lt;span style="color: blue"&gt;true&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;Logger&lt;/span&gt;.Write(&lt;span style="color: #a31515"&gt;"Calculation cancelled by user!"&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Category&lt;/span&gt;.General, &lt;span style="color: #2b91af"&gt;Priority&lt;/span&gt;.High);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;上述代码使用了Logger.Write的重载方法，省略了创建一个LogEntry对象。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面继续针对Calculator.cs文件中OnCalculatorException方法，记录异常信息，添加如下代码：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;protected&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; OnCalculatorException(&lt;span style="color: #2b91af"&gt;CalculatorExceptionEventArgs&lt;/span&gt; args)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (!(args.Exception &lt;span style="color: blue"&gt;is&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ConfigurationErrorsException&lt;/span&gt;))&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;Logger&lt;/span&gt;.Write(args.Exception, &lt;span style="color: #2b91af"&gt;Category&lt;/span&gt;.General, &lt;span style="color: #2b91af"&gt;Priority&lt;/span&gt;.High);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (CalculatorException != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                CalculatorException(&lt;span style="color: blue"&gt;this&lt;/span&gt;, args);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-indent: -10.5pt; margin: 0cm 0cm 0pt 10.5pt"&gt;注意：确保Exception类型不是ConfigurationErrorsException，否则因为没有正确配置Logging Application Block，将不能Logger来记录日志。一般情况下，我们使用Enterprise Library的Exception Handling Application Block来创建一致的异常处理策略。&lt;/div&gt;
&lt;div style="text-indent: -10.5pt; margin: 0cm 0cm 0pt 10.5pt"&gt; &lt;/div&gt;
&lt;div style="text-indent: -10.5pt; margin: 0cm 0cm 0pt 10.5pt"&gt;3. 配置文件&lt;/div&gt;
&lt;div style="text-indent: -10.5pt; margin: 0cm 0cm 0pt 10.5pt"&gt;使用EntLib 的Enterprise Library Configuration工具打开app.config配置文件，添加Logging Application Block配置项。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center; text-indent: -10.5pt; margin: 0cm 0cm 0pt 10.5pt"&gt;&lt;img alt="" width="626" height="307" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_1_2.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;默认的Logging Application Block 配置项定义了一个General 的Category Source，General 目录有一个TraceListener的引用，名称为Formatted EventLog TraceListener。可以点击Category Sources节点，添加新的Category。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;选择Logging Application Block | Trace Listeners | Formatted EventLog TraceListener 节点，设置Source 属性为 EnoughPI（注意：Source需要在Event Log中注册，在第一次使用时，Event Log Trace Listener自动注册一个新的Source，但是需要有管理员的权限，因此第一次需要以管理员的权限运行该应用程序）。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_1_3.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;保存上述对app.config 文件的更新。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 运行范例程序&lt;/div&gt;
&lt;div&gt;从事件日志（Event Log）查看生成的log记录。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="640" height="474" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_1_4.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;5. 为应用程序添加跟踪功能&lt;/div&gt;
&lt;div&gt;打开Calc\Calculator.cs 文件，添加tracing代码。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; Calculate(&lt;span style="color: blue"&gt;int&lt;/span&gt; digits)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;StringBuilder&lt;/span&gt; pi = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;StringBuilder&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"3"&lt;/span&gt;, digits + 2);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;string&lt;/span&gt; result = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt; &lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;try&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;if&lt;/span&gt; (digits &amp;gt; 0)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Tracer&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Category&lt;/span&gt;.Trace))&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                        pi.Append(&lt;span style="color: #a31515"&gt;"."&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                        &lt;span style="color: blue"&gt;for&lt;/span&gt; (&lt;span style="color: blue"&gt;int&lt;/span&gt; i = 0; i &amp;lt; digits; i += 9)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            &lt;span style="color: #2b91af"&gt;CalculatingEventArgs&lt;/span&gt; args;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            args = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;CalculatingEventArgs&lt;/span&gt;(pi.ToString(), i + 1);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            OnCalculating(args);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            &lt;span style="color: green"&gt;// Break out if cancelled&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            &lt;span style="color: blue"&gt;if&lt;/span&gt; (args.Cancel == &lt;span style="color: blue"&gt;true&lt;/span&gt;) &lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            &lt;span style="color: green"&gt;// Calculate next 9 digits&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            &lt;span style="color: blue"&gt;int&lt;/span&gt; nineDigits = &lt;span style="color: #2b91af"&gt;NineDigitsOfPi&lt;/span&gt;.StartingAt(i + 1);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            &lt;span style="color: blue"&gt;int&lt;/span&gt; digitCount = &lt;span style="color: #2b91af"&gt;Math&lt;/span&gt;.Min(digits - i, 9);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            &lt;span style="color: blue"&gt;string&lt;/span&gt; ds = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;"{0:D9}"&lt;/span&gt;, nineDigits);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            pi.Append(ds.Substring(0, digitCount));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt; &lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                result = pi.ToString();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt; &lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: green"&gt;// Tell the world I've finished!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                OnCalculated(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;CalculatedEventArgs&lt;/span&gt;(result));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;catch&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Exception&lt;/span&gt; ex)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: green"&gt;// Tell the world I've crashed!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                OnCalculatorException(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;CalculatorExceptionEventArgs&lt;/span&gt;(ex));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt; &lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;return&lt;/span&gt; result;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;我们经常需要记录应用程序不同部分的运行时间，Logging Application Block的Tracing功能提供了对代码块记录执行时间的功能。Tracer对象在销毁时，会停止计时，并记录结束跟踪的消息。using 代码块可以确保在代码结束时，调用Tracer对象的Dispose() 方法。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;再次使用EntLib的配置工具打开app.config配置文件，选择Logging Application Block节点，设置TracingEnabled属性为True（默认为True）。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;选择Logging Application Block | Trace Listeners 节点，添加新的FlatFile TraceListener。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="590" height="407" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_1_5.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;并设置Formatter属性为Text Formatter，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="450" height="260" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_1_6.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;选择 Logging Application Block | Category Sources 节点，添加一个新的Category，并设置相应的属性。&lt;/div&gt;
&lt;div&gt;Name = Trace&lt;/div&gt;
&lt;div&gt;SourceLevels = ActivityTracing&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="697" height="423" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_1_7.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;这里的Trace Category 在前面的代码中有使用到，ActivityTracing 限制仅仅在开始和结束时跟踪日志。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;右键点击上一步创建的Trace Category，添加新的Trace Listener引用，并设置ReferencedTraceListener属性为 FlatFile TraceListener。其实，就是引用前一步创建的FlatFile TraceListener。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="601" height="273" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_1_8.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;保存app.config配置文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;6. 再次运行范例程序，检查trace.log文件。&lt;/div&gt;
&lt;div&gt;在应用程序的bin目录下，可以找到trace.log文件，记录了trace 开始和结束的相关信息，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="637" height="472" src="/userfiles/entlibforum/image/EnterpriseLibrary/Logging/loggingApplicationBlock_1_9.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.entlib.com/"&gt;http://www.entlib.com&lt;/a&gt;专业ASP.NET电子商务平台小组，欢迎你继续访问下一节内容。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Logging Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/201.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Exception Handling Application Block 学习手册（最新版） Part 2</title><link>http://blog.entlib.com/entlibforum/archive/2009/09/01/enterprise-library-exception-handling-application-block-part-2.aspx</link><pubDate>Mon, 31 Aug 2009 21:52:29 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/09/01/enterprise-library-exception-handling-application-block-part-2.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/200.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/200.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/09/01/enterprise-library-exception-handling-application-block-part-2.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/200.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Exception Handling Application Block 学习手册（最新版） Part 2</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Exception Handling Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版） Part 2&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文演示Enterprise Library – Exception Handling Application Block 异常管理模块的使用，如何将异常日志记录添加到应用程序中，以及如何使用Replace Handler隐藏敏感信息。本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习二：异常管理策略&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;本文练习如何使用代码访问安全来保护应用程序功能，并使用Exception Handling Application Block的Replace Handler隐藏敏感信息在客户端的显示。&lt;/div&gt;
&lt;div&gt;1. 首先打开\Enterprise Library 4.1 HOL\CS\Exception Handling\exercises\ex02\begin 目录下的Puzzler2.sln 项目文件。接着打开PuzzlerService 项目中的DictionaryService.cs 代码文件，DictionaryService类作为Dictionary类的服务接口（Service Interface），在这个类中，在发生异常信息到客户端之前，实现了异常信息的过滤和转换。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 对Add Word 功能实施代码访问安全（Code Access Security）&lt;/div&gt;
&lt;div&gt;打开PuzzlerService项目中的Dictionary.cs 代码文件，找到AddWord方法，添加安全属性，如下所示：&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;PrincipalPermission&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;SecurityAction&lt;/span&gt;.Demand, Role = &lt;span style="color: #a31515"&gt;"EntLib.com Administrator"&lt;/span&gt;)]&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Boolean&lt;/span&gt; AddWord(&lt;span style="color: blue"&gt;string&lt;/span&gt; wordToAdd)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (!IsWord(wordToAdd))&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: green"&gt;// It is not alphabetic! Throw an exception&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ApplicationException&lt;/span&gt;(&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: #a31515"&gt;"Word to add does not consist of alphabetic letters"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (Dict[wordToAdd] == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                Dict.Add(wordToAdd, wordToAdd);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;true&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;上述方法仅允许EntLib.com Administrator角色的成员调用（注：是在Dictionary.cs文件上，而不是DictionaryService.cs 文件上做上述修改。）&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 运行应用程序&lt;/div&gt;
&lt;div&gt;选择Debug | Start Without Debugging菜单项运行应用程序，在Word To Check 文本框输入一个单词（如abc123），将调用AddWord方法，抛出SecurityException异常，可以检查事件日志看到如下信息：&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="640" height="444" src="/userfiles/entlibforum/image/EnterpriseLibrary/ExceptionManagement_2_1.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;SecurityException可能从Server端序列化，传送到Client端，且有可能包含有敏感信息，对攻击者提供帮助。因此，我们希望在Server端捕获并记录安全异常，然后传递包含较少的异常信息到Client端。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 配置应用程序替换SecurityException&lt;/div&gt;
&lt;div&gt;在PuzzlerUI项目中，使用EntLib 附带的配置管理工具打开app.config 配置文件（具体操作可以参考Data Access Application Block的学习手册，这里不再重复了）。&lt;/div&gt;
&lt;div&gt;app.config 配置文件中已经包含了一个空的policy，名称为Service Policy。默认情况下，这个policy是空的，因此异常信息将在catch代码块中重新抛出，事实上该policy没有任何作用。&lt;/div&gt;
&lt;div&gt;下面选择Service Policy 节点，然后选择 New | Exception Type 菜单项，在弹出对话框中选择mscorlib 的System.Security.SecurityException类型，并点击 OK 按钮，如下图所示。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="605" height="364" src="/userfiles/entlibforum/image/EnterpriseLibrary/ExceptionManagement_2_2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="539" height="427" src="/userfiles/entlibforum/image/EnterpriseLibrary/ExceptionManagement_2_3.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;注：你可以使用类型选择器（Type Selector）轻松过滤Exception类型。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;接着选择  Service Policy |SecurityException 节点，并设置如下属性：&lt;/div&gt;
&lt;div&gt;PostHandlingAction = ThrowNewException&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="665" height="378" src="/userfiles/entlibforum/image/EnterpriseLibrary/ExceptionManagement_2_4.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;然后选择 Service Policy |SecurityException 节点，添加一个新的Logging Handler，并设置如下属性：&lt;/div&gt;
&lt;div&gt;FormatterType = TextExceptionFormatter&lt;/div&gt;
&lt;div&gt;LogCategory = General&lt;/div&gt;
&lt;div&gt;Title = Security Exception in Service Layer&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="637" height="396" src="/userfiles/entlibforum/image/EnterpriseLibrary/ExceptionManagement_2_5.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;下一步再选择 Service Policy | SecurityException 节点，添加新的Replace Handler，并设置相应属性：&lt;/div&gt;
&lt;div&gt;ExceptionMessage = Unauthorized Access&lt;/div&gt;
&lt;div&gt;ReplaceExceptionType = System.Security.SecurityException (from mscorlib)&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="618" height="303" src="/userfiles/entlibforum/image/EnterpriseLibrary/ExceptionManagement_2_6.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;尽管上述操作还是保留相同的Exception类型，但通过创建一个新的SecurityException，可以对Client端不提供任何stack信息或内部安全异常信息，这样可以达到安全目的。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;5. 设置应用程序遇到安全异常时退出&lt;/div&gt;
&lt;div&gt;选择UI Policy节点，添加一个新的Exception 类型 – System.Security.SecurityException，并设置如下属性：PostHandlingAction = NotifyRethrow&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/ExceptionManagement_2_7.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;将PostHandlingAction 属性设置为NotifyRethrow时，Application.ThreadException 事件的handler将重新抛出异常。重新抛出的异常为未捕获异常，.NET Framework的CLR将强制关闭应用程序。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Application_ThreadException(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;ThreadExceptionEventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            HandleException(e.Exception, &lt;span style="color: #a31515"&gt;"UI Policy"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下一步再选择 UI Policy | SecurityException 节点，添加新的Logging Handler，并设置如下属性：&lt;/div&gt;
&lt;div&gt;FormatterType = TextExceptionFormatter&lt;/div&gt;
&lt;div&gt;LogCategory = General&lt;/div&gt;
&lt;div&gt;Title = Security Exception in UI Layer&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="638" height="449" src="/userfiles/entlibforum/image/EnterpriseLibrary/ExceptionManagement_2_8.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;最后，别忘记保存app.config 配置文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;6. 测试Replace Handler&lt;/div&gt;
&lt;div&gt;选择Debug | Start Without Debugging 菜单项，运行应用程序。&lt;/div&gt;
&lt;div&gt;在Word To Check 文本框中，输入一个错误的单词（确保错误的图标出现），然后点击Add Word按钮。将弹出一个对话框，显示Unhandled exception消息。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面打开Event Log，查看事件日志，这一次Event Log 中将有三条Excpetion记录。&lt;/div&gt;
&lt;div&gt;第一条是Dictionary.cs抛出的SecurityExcepiton异常，在Service Layer（DictionaryService.cs）捕获，应用Service Policy。&lt;/div&gt;
&lt;div&gt;&lt;span style="color: #2b91af; font-size: 9pt"&gt;ExceptionPolicy&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;.HandleException(ex,&lt;span style="color: #a31515"&gt; "Service Policy"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;将异常记录到Server端的事件日志（包含有所有信息）。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;第二条是替换过的SecurityException异常，在Startup.cs的ThreadException handler中捕获（&lt;a href="http://blog.entlib.com/"&gt;http://blog.EntLib.com&lt;/a&gt; 开源博客小组注：这里捕获的异常是Server端重新抛出的异常），并应用 UI Policy。&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;HandleException(e.Exception, &lt;span style="color: #a31515"&gt;"UI Policy"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;将异常记录到Client端的事件日志（本范例是同一台机器）。前面在app.config中配置重新抛出异常，因此将重新抛出上述接收到的SecurityException异常。&lt;/div&gt;
&lt;div&gt;第三条是前一步重新抛出的SecurityException 被AppDomain的UnhandledException handler捕获（在Application.Run线程之外抛出），并应用Unhandled Policy。&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;HandleException((System.&lt;span style="color: #2b91af"&gt;Exception&lt;/span&gt;)e.ExceptionObject, &lt;span style="color: #a31515"&gt;"Unhandled Policy"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;将记录异常信息，并显示一个消息对话框，提醒用户应用程序有错误。AppDomain UnhandledException handler并不好吸收该异常，因此异常将继续传递到Runtime或者Debugger调试器，这将导致一个标准的unhandled exception对话框弹出。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;为了准确理解上述的学习教程，建议仔细阅读下面的这段文字。这段文字摘录自Enterprise Library – Exception Handling Application Block帮助文档，介绍了Exception Type的配置。&lt;/div&gt;
&lt;div&gt;&lt;b&gt;Configuring Exception Types&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Each exception policy can be configured to handle specific exception types. An application passes the exception to be handled and the name of the policy that should be used to handle the exception to the Exception Handling Application Block. The application block looks at the policy to see if it has been configured to handle exceptions of that type.&lt;b&gt; If it finds a match, the application block executes the series of exception handlers. The application block tries to match the exception type to the most specific type of exception listed in the configuration file. If it does not find a match, the application block looks for base class exception types.&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;In this way, an application can be configured for particular actions for specific exception types (for example, it can wrap or replace exceptions of type System.SecurityException with a custom application exception type), but it can have different actions for more generic exception types (for example, it can log exceptions of type System.Exception). Each exception type can be configured to indicate the action the application block will take after the chain of exception handlers runs for that exception type.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组，欢迎你继续方法下一节内容：Logging application block。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Exception Handling Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/200.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library - Exception Handling Application Block 学习手册（最新版）Part 1</title><link>http://blog.entlib.com/entlibforum/archive/2009/08/31/enterprise-library-exception-handling-application-block-part-1.aspx</link><pubDate>Sun, 30 Aug 2009 21:57:20 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/08/31/enterprise-library-exception-handling-application-block-part-1.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/199.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/199.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/08/31/enterprise-library-exception-handling-application-block-part-1.aspx#comment</comments><slash:comments>8</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/199.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library - Exception Handling Application Block 学习手册（最新版）Part 1</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library - Exception Handling Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版）Part 1&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文演示Enterprise Library – Exception Handling Application Block 异常管理模块的使用，如何将异常日志记录添加到应用程序中，以及如何使用Replace Handler隐藏敏感信息。本文由&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组根据EntLib HOL手册编译提供，欢迎交流。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;练习一：记录异常日志&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;1. 首先打开\Enterprise Library 4.1 HOL\CS\Exception Handling\exercises\ex01\begin 目录下的Puzzler.sln 项目文件。&lt;/div&gt;
&lt;div&gt;该应用程序执行2个功能：检查单词的拼写；根据字符列表，使用字典生成单词列表。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;运行应用程序，界面如下所示。在单词文本输入框，输入 ab123，然后点击 Add Word 按钮，将抛出一个未捕获异常。&lt;/div&gt;
&lt;div style="text-align: center"&gt; &lt;img alt="" width="477" height="350" src="/userfiles/entlibforum/image/EnterpriseLibrary/ExceptionManagement_1_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt;下面实现如何使用Exception Handling Application Block，进行异常管理。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 选择PuzzlerUI 项目，添加如下dll 的引用。&lt;/div&gt;
&lt;div&gt;Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.dll&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 打开Puzzler.cs 代码文件，添加对ExcepitonHandling 命名空间的引用。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; Microsoft.Practices.EnterpriseLibrary.ExceptionHandling; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;找到btnAddWord_Click 方法，添加try/catch 代码块，如下所示：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; btnAddWord_Click(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, System.&lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;try&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: green"&gt;// TODO: Handle exceptions&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                PuzzlerService.&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;.AddWord(txtWordToCheck.Text);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                errorProvider1.SetError(txtWordToCheck, &lt;span style="color: #a31515"&gt;""&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;catch&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Exception&lt;/span&gt; ex)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;bool&lt;/span&gt; rethrow = &lt;span style="color: #2b91af"&gt;ExceptionPolicy&lt;/span&gt;.HandleException(ex, &lt;span style="color: #a31515"&gt;"UI Policy"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;if&lt;/span&gt; (rethrow)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: blue"&gt;throw&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;MessageBox&lt;/span&gt;.Show(&lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: #a31515"&gt;"Failed to add word {0}, please contact support."&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    txtWordToCheck.Text));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 为 PuzzlerUI 项目添加app.config配置文件，并使用EntLib附带的配置文件编辑器打开配置文件。然后，添加 Exception Handling Application Block 的配置，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="686" height="352" src="/userfiles/entlibforum/image/EnterpriseLibrary/ExceptionManagement_1_2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;接下来，添加新的Exception Policy，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="613" height="318" src="/userfiles/entlibforum/image/EnterpriseLibrary/ExceptionManagement_1_3.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;设置Exception Policy的Name属性为 UI Policy，该Policy的名称需要和前面的代码中保持一致。&lt;/div&gt;
&lt;div&gt;&lt;span style="color: blue; font-size: 9pt"&gt;bool&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; rethrow = &lt;span style="color: #2b91af"&gt;ExceptionPolicy&lt;/span&gt;.HandleException(ex, &lt;span style="color: #a31515"&gt;"UI Policy"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;选择UI Policy 节点，添加新的Exception Type，如下图所示。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="614" height="293" src="/userfiles/entlibforum/image/EnterpriseLibrary/ExceptionManagement_1_4.gif" /&gt; &lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;在弹出的Type Selector对话框中，选择System.Exception类型，如下图所示。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="539" height="427" src="/userfiles/entlibforum/image/EnterpriseLibrary/ExceptionManagement_1_5.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;这个filter设置哪一类的Exception由异常处理代码来负责处理，将处理所有继承自System.Exception 类型的异常。另外，设置System.Exception类型的PostHandlingAction属性为None，该属性值None表示所有的异常将在异常处理代码内部处理，调用方（caller）不需要在catch代码块中重新抛出异常。&lt;/div&gt;
&lt;div&gt;下面进一步选择Exception Handling Application Block | UI Policy | Exception 节点，并选择 New | Logging Handler 菜单项，如下图所示。这一步操作将自动添加Logging Application Block到配置文件中，你可以观察一下app.config 配置文件的变化。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="634" height="322" src="/userfiles/entlibforum/image/EnterpriseLibrary/ExceptionManagement_1_6.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;选择 Exception Handling Application Block | UI Policy | Exception | Logging Handler 节点，设置如下属性：&lt;/div&gt;
&lt;div&gt;FormatterType = TextExceptionFormatter&lt;/div&gt;
&lt;div&gt;LogCategory = General&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="450" height="303" src="/userfiles/entlibforum/image/EnterpriseLibrary/ExceptionManagement_1_7.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;上述配置操作完成后，记得要保存配置文件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;5. 设置PuzzlerUI 项目添加对如下dll引用。&lt;/div&gt;
&lt;div&gt;Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.dll&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;因为Enterprise Library 的一个目标是保持Application Blocks之间相互低耦合，因此Exception Handling Application Block也可以不必使用Logging Application Block（例如，创建自己的异常管理Handler）。如果你使用两个application blocks，你需要引用上述的dll， Exception Handler来通过logging application block 来记录异常日志（默认安装情况下，该dll在如下目录C:\Program Files\Microsoft Enterprise Library 4.1 - October 2008\Bin）。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;6. 再次运行应用程序&lt;/div&gt;
&lt;div&gt;重复前面的步骤，在单词文本输入框，输入abc123，然后点击 Add Word 按钮，将弹出一个对话框 – Failed to add word abc123, please contact support。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="610" height="404" src="/userfiles/entlibforum/image/EnterpriseLibrary/ExceptionManagement_1_8.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;检查windows的事件日志（Event Log），查看Application 日志，发现日志信息已经记录了。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/ExceptionManagement_1_9.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;为了在应用程序中给所有的代码添加try/catch，你可以考虑添加一个全局的Exception Handler。有2个events可以用来监听未捕获异常（unhandled exception）：&lt;/div&gt;
&lt;div&gt;（1）当执行Application.Run 方法的线程发生未捕获异常时，触发Application.ThreadException事件。&lt;/div&gt;
&lt;div&gt;（2）如果handler抛出异常，或者不在UI线程中发生异常，将触发AppDomain.UnhandledException事件。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;7. 更新代码&lt;/div&gt;
&lt;div&gt;（1）删除之前btnAddWord_Click方法中添加的代码，如下所示：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; btnAddWord_Click(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, System.&lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            PuzzlerService.&lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;.AddWord(txtWordToCheck.Text);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            errorProvider1.SetError(txtWordToCheck, &lt;span style="color: #a31515"&gt;""&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;（2）打开Startup.cs代码文件，添加命名空间的引用。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; Microsoft.Practices.EnterpriseLibrary.ExceptionHandling; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;同时，在Startup类中添加如下方法来处理异常。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; HandleException(&lt;span style="color: #2b91af"&gt;Exception&lt;/span&gt; ex, &lt;span style="color: blue"&gt;string&lt;/span&gt; policy)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Boolean&lt;/span&gt; rethrow = &lt;span style="color: blue"&gt;false&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;try&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                rethrow = &lt;span style="color: #2b91af"&gt;ExceptionPolicy&lt;/span&gt;.HandleException(ex, policy);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;catch&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Exception&lt;/span&gt; innerEx)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;string&lt;/span&gt; errorMsg = &lt;span style="color: #a31515"&gt;"An unexpected exception occured while "&lt;/span&gt; +&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: #a31515"&gt;"calling HandleException with policy '"&lt;/span&gt; + policy + &lt;span style="color: #a31515"&gt;"'. "&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                errorMsg += &lt;span style="color: #2b91af"&gt;Environment&lt;/span&gt;.NewLine + innerEx.ToString();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;MessageBox&lt;/span&gt;.Show(errorMsg, &lt;span style="color: #a31515"&gt;"Application Error"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: #2b91af"&gt;MessageBoxButtons&lt;/span&gt;.OK, &lt;span style="color: #2b91af"&gt;MessageBoxIcon&lt;/span&gt;.Stop);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;throw&lt;/span&gt; ex;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (rethrow)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: green"&gt;// WARNING: This will truncate the stack of the exception&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;throw&lt;/span&gt; ex;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;MessageBox&lt;/span&gt;.Show(&lt;span style="color: #a31515"&gt;"An unhandled exception occurred and has "&lt;/span&gt; +&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: #a31515"&gt;"been logged. Please contact support."&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;上述方法使用Exception Handling Application Block，如果Exception Handling Application Block自身发生问题（如遗漏配置项），也将显示有效的信息。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;继续添加如下的方法作为应用程序的ThreadException事件的event handler：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Application_ThreadException(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;ThreadExceptionEventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            HandleException(e.Exception, &lt;span style="color: #a31515"&gt;"UI Policy"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;上述方法使用前面定义过的UI Policy。在随后的练习中，将定制这一Policy，允许忽略某些异常，并关闭应用程序。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面继续添加AppDomain的UnhandledException 事件的Event Handler：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; CurrentDomain_UnhandledException(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;UnhandledExceptionEventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (e.ExceptionObject &lt;span style="color: blue"&gt;is&lt;/span&gt; System.&lt;span style="color: #2b91af"&gt;Exception&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                HandleException((System.&lt;span style="color: #2b91af"&gt;Exception&lt;/span&gt;)e.ExceptionObject, &lt;span style="color: #a31515"&gt;"Unhandled Policy"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;上述代码使用了一个新的policy（Unhandled Policy），下一节将创建。Unhandled Policy 总是仅记录异常，并不重抛异常。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;最后，在Main方法中，通过如下代码连接event handler和事件：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;         &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Main() &lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;         {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;.ThreadException += &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ThreadExceptionEventHandler&lt;/span&gt;(Application_ThreadException);&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;AppDomain&lt;/span&gt;.CurrentDomain.UnhandledException += &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;UnhandledExceptionEventHandler&lt;/span&gt;(CurrentDomain_UnhandledException);&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;              &lt;span style="color: #2b91af"&gt;Puzzler&lt;/span&gt; f = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Puzzler&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;              &lt;span style="color: #2b91af"&gt;Application&lt;/span&gt;.Run(f);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;         }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;再次运行应用程序，重复前面的测试步骤，检查弹出的消息对话框和事件日志中的异常记录，确认完成了上述所有步骤，且应用程序工作和预期一致。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://blog.entlib.com/"&gt;http://blog.entlib.com&lt;/a&gt; 开源ASP.NET博客平台小组，欢迎你继续方法下一节内容：Exception Handling application block – 异常管理策略。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;参考文档：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Exception Handling Application Block Hands-On Labs for Enterprise Library&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/199.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library – Data Access Application Block 学习手册（最新版）- Part 3</title><link>http://blog.entlib.com/entlibforum/archive/2009/08/27/enterprise-library-data-access-application-block-part-3.aspx</link><pubDate>Wed, 26 Aug 2009 20:25:27 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/08/27/enterprise-library-data-access-application-block-part-3.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/198.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/198.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/08/27/enterprise-library-data-access-application-block-part-3.aspx#comment</comments><slash:comments>11</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/198.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library – Data Access Application Block 学习手册（最新版）- Part 3</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library – Data Access Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版）- Part 3&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Enterprise Library for .Net Framework 3.5 – EntLib v4.1 是patterns &amp;amp; practices 小组为.NET Framework 3.5 开发一套企业库，目前最新版本为v4.1，共包括9个Application Block，包括数据访问（Data Access Application Block）、异常管理（Exception Handling Application Block）、数据验证（Validation Application Block）等等，对企业应用开发非常有帮助，也非常实用。&lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="600" height="85" src="/userfiles/entlibforum/image/EnterpriseLibrary/entlib_accelerator2.jpg" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;相关下载信息：&lt;/div&gt;
&lt;div&gt;&lt;a href="http://blog.entlib.com/EntLib/archive/2009/03/30/enterprise-library-for-.net-framework-3.5-entlib-v4.1-v4.1.aspx"&gt;http://blog.entlib.com/EntLib/archive/2009/03/30/enterprise-library-for-.net-framework-3.5-entlib-v4.1-v4.1.aspx&lt;/a&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;上一篇：&lt;a href="http://blog.entlib.com/entlibforum/archive/2009/08/26/enterprise-library-data-access-application-block-part-2.aspx"&gt;Enterprise Library &lt;span&gt;&lt;span&gt;–&lt;/span&gt; Data Access Application Block &lt;span&gt;学习手册（最新版）&lt;/span&gt;- Part 2&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文根据EntLib v4.1 的学习手册（Hands on Lab），演示如何加密配置文件中连接字符串。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;1. 下面就可以打开项目 \Enterprise Library 4.1 HOL\CS\Data Access\exercises\ex03\begin \DataEx3.sln 开始我们的工作了。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 打开项目中的app.config 配置文件，检查数据库连接字符串是否正确，目前connection string是明文，尚未加密。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" src="/userfiles/entlibforum/image/EnterpriseLibrary/DAAB_HOL_3_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 加密数据库连接字符串&lt;/div&gt;
&lt;div&gt;选择app.config 配置文件，使用Enterprise Library Configuration 工具打开。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="440" height="358" src="/userfiles/entlibforum/image/EnterpriseLibrary/DAAB_HOL_3_2.gif" /&gt; &lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;如下图所示，选择Data Access Application Block，然后在属性窗口中，选择ProtectionProvider属性，并设置该属性为RsaProtectedConfigurationProvider。保存后，重新回到app.config在Visual Studio 的编辑界面。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt; &lt;img alt="" width="604" height="397" src="/userfiles/entlibforum/image/EnterpriseLibrary/DAAB_HOL_3_3.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;现在，你会发现配置文件中的connection string 字符串已经加密了。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="697" height="490" src="/userfiles/entlibforum/image/EnterpriseLibrary/DAAB_HOL_3_4.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;但是，现在你运行范例程序，和前面一样，运行正常。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;EntLib.com 开源论坛小组（&lt;a href="http://forum.entlib.com/"&gt;http://forum.entlib.com&lt;/a&gt;）欢迎你继续访问后续内容。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/198.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library – Data Access Application Block 学习手册（最新版）- Part 2</title><link>http://blog.entlib.com/entlibforum/archive/2009/08/26/enterprise-library-data-access-application-block-part-2.aspx</link><pubDate>Tue, 25 Aug 2009 20:41:20 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/08/26/enterprise-library-data-access-application-block-part-2.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/197.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/197.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/08/26/enterprise-library-data-access-application-block-part-2.aspx#comment</comments><slash:comments>0</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/197.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library – Data Access Application Block 学习手册（最新版）- Part 2</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library – Data Access Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版）- Part 2&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Enterprise Library for .Net Framework 3.5 – EntLib v4.1 是patterns &amp;amp; practices 小组为.NET Framework 3.5 开发一套企业库，目前最新版本为v4.1，共包括9个Application Block，包括数据访问（Data Access Application Block）、异常管理（Exception Handling Application Block）、数据验证（Validation Application Block）等等，对企业应用开发非常有帮助，也非常实用。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="600" height="85" src="/userfiles/entlibforum/image/EnterpriseLibrary/entlib_accelerator2.jpg" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;相关下载信息：&lt;/div&gt;
&lt;div&gt;&lt;a href="http://blog.entlib.com/EntLib/archive/2009/03/30/enterprise-library-for-.net-framework-3.5-entlib-v4.1-v4.1.aspx"&gt;http://blog.entlib.com/EntLib/archive/2009/03/30/enterprise-library-for-.net-framework-3.5-entlib-v4.1-v4.1.aspx&lt;/a&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;上一篇：&lt;a href="http://blog.entlib.com/entlibforum/archive/2009/08/26/enterprise-library-data-access-application-block-part-2.aspx"&gt;Enterprise Library – Data Access Application Block 学习手册（最新版）- Part 1&lt;/a&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文根据EntLib v4.1 的学习手册（Hands on Lab），演示数据访问存储过程及更新数据记录。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;在开始之前，先要执行如下的SQL 脚本，创建相关的数据表和存储过程：Enterprise Library 4.1 HOL\CS\Data Access\exercises\ex02\DbSetup 目录下的Categories.sql 和 HOLSPs.sql。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;1. 下面就可以打开项目 \Enterprise Library 4.1 HOL\CS\Data Access \exercises \ex02 \begin \DataEx2.sln 开始我们的工作了。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;打开MainForm.cs 代码文件，添加对Namespace的引用：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; Microsoft.Practices.EnterpriseLibrary.Data; &lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div&gt;同时在Form 中创建如下private Database变量：&lt;/div&gt;
&lt;div&gt;&lt;span style="color: blue; font-size: 9pt"&gt;private&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; &lt;span style="color: #2b91af"&gt;Database&lt;/span&gt; _db = &lt;span style="color: #2b91af"&gt;DatabaseFactory&lt;/span&gt;.CreateDatabase(&lt;span style="color: #a31515"&gt;"QuickStarts Instance"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 编写代码&lt;/div&gt;
&lt;div&gt;在MainForm_Load 方法编写如下代码，调用GetCategories 存储过程，返回DataReader 数据对象，在using 语句块结束后，自动释放数据库连接。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; MainForm_Load(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, System.&lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;this&lt;/span&gt;.cmbCategory.Items.Clear();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;IDataReader&lt;/span&gt; dataReader = _db.ExecuteReader(&lt;span style="color: #a31515"&gt;"GetCategories"&lt;/span&gt;))&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: green"&gt;// Processing code &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;while&lt;/span&gt; (dataReader.Read())&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: #2b91af"&gt;Category&lt;/span&gt; item = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Category&lt;/span&gt;(&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                          dataReader.GetInt32(0),&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                          dataReader.GetString(1),&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                          dataReader.GetString(2));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: blue"&gt;this&lt;/span&gt;.cmbCategory.Items.Add(item);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: blue"&gt;this&lt;/span&gt;.cmbCategory.Items.Count &amp;gt; 0)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;this&lt;/span&gt;.cmbCategory.SelectedIndex = 0;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面的方法实现在Category下来列表框改变时，同步更新DataGrid中的产品记录。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; cmbCategory_SelectedIndexChanged(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, System.&lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;this&lt;/span&gt;.dsProducts.Clear();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Category&lt;/span&gt; selectedCategory = (&lt;span style="color: #2b91af"&gt;Category&lt;/span&gt;) &lt;span style="color: blue"&gt;this&lt;/span&gt;.cmbCategory.SelectedItem;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (selectedCategory == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            _db.LoadDataSet(&lt;span style="color: #a31515"&gt;"GetProductsByCategory"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;this&lt;/span&gt;.dsProducts,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt;[] { &lt;span style="color: #a31515"&gt;"Products"&lt;/span&gt; },&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                selectedCategory.CategoryId);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;Database类提供了2个方法填充DataSet，分别是ExecuteDataSet和LoadDataSet。ExecuteDataSet方法返回一个新创建的DataSet 对象；LoadDataSet则填充一个现有的DataSet对象。上述的LoadDataSet方法传入的第一个参数是GetProductsByCategory 存储过程的名称，第二个参数是待填充的DataSet变量，第三个参数是将存储过程返回的结果集映射到指定的一组表名，最后一个参数的传给存储过程的参数值，这里为CategoryID。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;接下来实现更新的方法，btnSave_Click 方法代码如下：&lt;/div&gt;
&lt;div style="text-align: left; text-indent: 21pt" align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;private&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; btnSave_Click(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, System.&lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            System.Data.Common.&lt;span style="color: #2b91af"&gt;DbCommand&lt;/span&gt; insertCommand = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            insertCommand = _db.GetStoredProcCommand(&lt;span style="color: #a31515"&gt;"HOLAddProduct"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            _db.AddInParameter(insertCommand, &lt;span style="color: #a31515"&gt;"ProductName"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;DbType&lt;/span&gt;.String, &lt;span style="color: #a31515"&gt;"ProductName"&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;DataRowVersion&lt;/span&gt;.Current);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            _db.AddInParameter(insertCommand, &lt;span style="color: #a31515"&gt;"CategoryID"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;DbType&lt;/span&gt;.Int32, &lt;span style="color: #a31515"&gt;"CategoryID"&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;DataRowVersion&lt;/span&gt;.Current);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            _db.AddInParameter(insertCommand, &lt;span style="color: #a31515"&gt;"UnitPrice"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;DbType&lt;/span&gt;.Currency, &lt;span style="color: #a31515"&gt;"UnitPrice"&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;DataRowVersion&lt;/span&gt;.Current);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            System.Data.Common.&lt;span style="color: #2b91af"&gt;DbCommand&lt;/span&gt; deleteCommand = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            deleteCommand = _db.GetStoredProcCommand(&lt;span style="color: #a31515"&gt;"HOLDeleteProduct"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            _db.AddInParameter(deleteCommand, &lt;span style="color: #a31515"&gt;"ProductID"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;               &lt;span style="color: #2b91af"&gt;DbType&lt;/span&gt;.Int32, &lt;span style="color: #a31515"&gt;"ProductID"&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;DataRowVersion&lt;/span&gt;.Current);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            _db.AddInParameter(deleteCommand, &lt;span style="color: #a31515"&gt;"LastUpdate"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;DbType&lt;/span&gt;.DateTime, &lt;span style="color: #a31515"&gt;"LastUpdate"&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;DataRowVersion&lt;/span&gt;.Original);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            System.Data.Common.&lt;span style="color: #2b91af"&gt;DbCommand&lt;/span&gt; updateCommand = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            updateCommand = _db.GetStoredProcCommand(&lt;span style="color: #a31515"&gt;"HOLUpdateProduct"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            _db.AddInParameter(updateCommand, &lt;span style="color: #a31515"&gt;"ProductID"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;               &lt;span style="color: #2b91af"&gt;DbType&lt;/span&gt;.Int32, &lt;span style="color: #a31515"&gt;"ProductID"&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;DataRowVersion&lt;/span&gt;.Current);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            _db.AddInParameter(updateCommand, &lt;span style="color: #a31515"&gt;"ProductName"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;               &lt;span style="color: #2b91af"&gt;DbType&lt;/span&gt;.String, &lt;span style="color: #a31515"&gt;"ProductName"&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;DataRowVersion&lt;/span&gt;.Current);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            _db.AddInParameter(updateCommand, &lt;span style="color: #a31515"&gt;"CategoryID"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;               &lt;span style="color: #2b91af"&gt;DbType&lt;/span&gt;.Int32, &lt;span style="color: #a31515"&gt;"CategoryID"&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;DataRowVersion&lt;/span&gt;.Current);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            _db.AddInParameter(updateCommand, &lt;span style="color: #a31515"&gt;"UnitPrice"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;DbType&lt;/span&gt;.Currency, &lt;span style="color: #a31515"&gt;"UnitPrice"&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;DataRowVersion&lt;/span&gt;.Current);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            _db.AddInParameter(updateCommand, &lt;span style="color: #a31515"&gt;"LastUpdate"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;DbType&lt;/span&gt;.DateTime, &lt;span style="color: #a31515"&gt;"LastUpdate"&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;DataRowVersion&lt;/span&gt;.Current);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;int&lt;/span&gt; rowsAffected = _db.UpdateDataSet(&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;this&lt;/span&gt;.dsProducts,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #a31515"&gt;"Products"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                insertCommand,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                updateCommand,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                deleteCommand,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;UpdateBehavior&lt;/span&gt;.Standard);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;在更新数据时，需要手动创建存储过程的外包层（Wrapper），建立数据表DataTable字段和存储过程参数的映射。Database类的UpdateDataSet这一方法比较少调用，这里不深入介绍了。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 检查配置文件app.config&lt;/div&gt;
&lt;div&gt;本范例程序的配置文件已经建立的，不过，可以检查一下数据库连接是否需要修改：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;xml&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;version&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt;1.0&lt;/span&gt;"&lt;span style="color: red"&gt;encoding&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;utf-8&lt;/span&gt;"&lt;span style="color: blue"&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;configuration&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;configSections&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;section&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;name&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt;dataConfiguration&lt;/span&gt;"&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;configSections&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;dataConfiguration&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;defaultDatabase&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt;QuickStarts Instance&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;connectionStrings&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;add&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;name&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;b&gt;&lt;span style="color: blue"&gt;QuickStarts Instance&lt;/span&gt;&lt;/b&gt;"&lt;span style="color: red"&gt;connectionString&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;Database=EntLibQuickStarts;Server=(local);Integrated Security=SSPI;&lt;/span&gt;"&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;      &lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;providerName&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt;System.Data.SqlClient&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;connectionStrings&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;configuration&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 运行范例程序，范例程序的运行界面如下：&lt;/div&gt;
&lt;div style="text-align: center"&gt; &lt;img alt="" width="565" height="401" src="/userfiles/entlibforum/image/EnterpriseLibrary/DAAB_HOL_6.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;欢迎继续访问后续内容。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/197.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>Enterprise Library – Data Access Application Block 学习手册（最新版）- Part 1</title><link>http://blog.entlib.com/entlibforum/archive/2009/08/26/enterprise-library-data-access-application-block-part-1.aspx</link><pubDate>Tue, 25 Aug 2009 20:02:13 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/08/26/enterprise-library-data-access-application-block-part-1.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/196.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/196.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/08/26/enterprise-library-data-access-application-block-part-1.aspx#comment</comments><slash:comments>3</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/196.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">Enterprise Library – Data Access Application Block 学习手册（最新版）- Part 1</source><description>&lt;div align="center"&gt;&lt;b&gt;Enterprise Library – Data Access Application Block &lt;/b&gt;&lt;b&gt;学习手册（最新版）- Part 1&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Enterprise Library for .Net Framework 3.5 – EntLib v4.1 是patterns &amp;amp; practices 小组为.NET Framework 3.5 开发一套企业库，目前最新版本为v4.1，共包括9个Application Block，包括数据访问（Data Access Application Block）、异常管理（Exception Handling Application Block）、数据验证（Validation Application Block）等等，对企业应用开发非常有帮助，也非常实用。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="600" height="85" src="/userfiles/entlibforum/image/EnterpriseLibrary/entlib_accelerator2.jpg" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;相关下载信息：&lt;/div&gt;
&lt;div&gt;&lt;a href="http://blog.entlib.com/EntLib/archive/2009/03/30/enterprise-library-for-.net-framework-3.5-entlib-v4.1-v4.1.aspx"&gt;http://blog.entlib.com/EntLib/archive/2009/03/30/enterprise-library-for-.net-framework-3.5-entlib-v4.1-v4.1.aspx&lt;/a&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文根据EntLib v4.1 的学习手册（Hands on Lab），演示数据访问模块的应用：&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;1. 下载EntLib v4.1 的 Hands on Lab (&lt;a href="http://www.codeplex.com/entlib"&gt;http://www.codeplex.com/entlib&lt;/a&gt; ) ，并进行安装。&lt;/div&gt;
&lt;div&gt;打开安装目录下的\Enterprise Library 4.1 HOL\CS\Data Access\exercises\ex01\begin 的SimpleData.sln 项目文件，就可以开始下面的工作了。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;在开始之前，还需要创建范例程序中访问的EntLibQuickStarts 数据库。&lt;/div&gt;
&lt;div&gt;创建数据库、表、及其存储过程的脚本文件：Enterprise Library 4.1 HOL\CS\Data Access\setup\ DataAccessQuickStarts.sql。在SQL SERVER 2005/2008 中打开，执行一下就可以了。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;2. 引用EntLib 中需要的DLL 文件，在安装的目录下 C:\Program Files\Microsoft Enterprise Library 4.1 - October 2008\Bin。这里，引用如下DLL 文件：&lt;/div&gt;
&lt;div&gt;Microsoft.Practices.EnterpriseLibrary.Common.dll&lt;/div&gt;
&lt;div&gt;Microsoft.Practices.EnterpriseLibrary.Data.dll&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;打开项目中 MainForm.cs 代码文件，添加应用的namespace的引用：&lt;/div&gt;
&lt;div&gt;using Microsoft.Practices.EnterpriseLibrary.Data;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;3. 添加代码：&lt;/div&gt;
&lt;div&gt;第一段代码是返回有多少条Customers记录。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; mnuCount_Click(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, System.&lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Database&lt;/span&gt; db = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            db = &lt;span style="color: #2b91af"&gt;DatabaseFactory&lt;/span&gt;.CreateDatabase(&lt;span style="color: #a31515"&gt;"QuickStarts Instance"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;int&lt;/span&gt; count = (&lt;span style="color: blue"&gt;int&lt;/span&gt;)db.ExecuteScalar(&lt;span style="color: #2b91af"&gt;CommandType&lt;/span&gt;.Text, &lt;span style="color: #a31515"&gt;"SELECT Count(*) From Customers"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;string&lt;/span&gt; message = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;"There are {0} customers in the database"&lt;/span&gt;, count.ToString());&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;MessageBox&lt;/span&gt;.Show(message);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;第二段代码是返回所有的Customers记录，并显示DataGrid中。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; mnuLoad_Click(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, System.&lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Database&lt;/span&gt; db = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            db = &lt;span style="color: #2b91af"&gt;DatabaseFactory&lt;/span&gt;.CreateDatabase();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;DataSet&lt;/span&gt; ds = db.ExecuteDataSet(&lt;span style="color: #2b91af"&gt;CommandType&lt;/span&gt;.Text, &lt;span style="color: #a31515"&gt;"SELECT * From Customers"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            dataGrid1.DataSource = ds.Tables[0];&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="704" height="610" src="/userfiles/entlibforum/image/EnterpriseLibrary/DAAB_HOL_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;到目前为止，还不能运行上述的代码，因为app.config 配置文件还没有创建，还不存在数据库连接。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;4. 创建app.config 配置文件，通过EntLib 附带的编辑器进行编辑，自动生成相应的配置文件，如下图所示，该编辑器与Visual Studio 2008 进行了集成。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="400" height="508" src="/userfiles/entlibforum/image/EnterpriseLibrary/DAAB_HOL_2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;如下图所示，通过编辑器，创建新的Connection String。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="632" height="219" src="/userfiles/entlibforum/image/EnterpriseLibrary/DAAB_HOL_3.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;并设置Connection String 具体信息。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="707" height="576" src="/userfiles/entlibforum/image/EnterpriseLibrary/DAAB_HOL_4.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;这里需要注意的几个地方是：&lt;/div&gt;
&lt;div&gt;（1）选择Connection String节点，更改Name 属性为 QuickStarts Instance，就是上面代码中创建Database时传入的参数值。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;（2）选择Data Access Application Block 节点，设置DefaultDatabase 属性为QuickStarts Instance。在上面的第二段代码中，创建Database对象时没有传入参数，就是这里定义的DefaultDatabase参数。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;保存上述配置信息，查看一下自动生成的配置文件：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;xml&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;version&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt;1.0&lt;/span&gt;"&lt;span style="color: red"&gt;encoding&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;utf-8&lt;/span&gt;"&lt;span style="color: blue"&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;configuration&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;configSections&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;section&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;name&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt;dataConfiguration&lt;/span&gt;"&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;configSections&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;dataConfiguration&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;defaultDatabase&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;b&gt;&lt;span style="color: blue"&gt;QuickStarts Instance&lt;/span&gt;&lt;/b&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;connectionStrings&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;add&lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;name&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;b&gt;&lt;span style="color: blue"&gt;QuickStarts Instance&lt;/span&gt;&lt;/b&gt;"&lt;span style="color: red"&gt;connectionString&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;Data Source=YOURCOMPUTERNAME;Initial Catalog=EntLibQuickStarts;Integrated Security=True&lt;/span&gt;"&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;      &lt;/span&gt;&lt;span style="color: red; font-size: 9pt"&gt;providerName&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;=&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;"&lt;span style="color: blue"&gt;System.Data.SqlClient&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;connectionStrings&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;configuration&lt;/span&gt;&lt;span style="color: blue; font-size: 9pt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;5. 现在就可以运行范例程序了，看看运行情况。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt; &lt;img alt="" width="587" height="416" src="/userfiles/entlibforum/image/EnterpriseLibrary/DAAB_HOL_5.gif" /&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;
欢迎继续访问后续的内容。&lt;br /&gt;
&lt;br /&gt;
 &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/196.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>推荐《Pro ASP.NET MVC Framework》-下载免费第二章</title><link>http://blog.entlib.com/entlibforum/archive/2009/04/28/pro-asp.net-mvc-framework.aspx</link><pubDate>Mon, 27 Apr 2009 22:18:19 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/04/28/pro-asp.net-mvc-framework.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/189.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/189.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/04/28/pro-asp.net-mvc-framework.aspx#comment</comments><slash:comments>1</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/189.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">推荐《Pro ASP.NET MVC Framework》-下载免费第二章</source><description>&lt;div style="text-align: center"&gt;&lt;strong&gt;推荐《Pro ASP.NET MVC Framework》-下载免费第二章&lt;/strong&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Apress《Pro ASP.NET MVC Framework》已经出版了，并且还提供ebook版本，感兴趣的可以访问如下链接：&lt;br /&gt;
&lt;a href="http://www.apress.com/book/view/9781430210078"&gt;http://www.apress.com/book/view/9781430210078&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
同时，Apress 网站还提供了第二章，供免费下载。该章共有23页，非常详细地介绍了整个创建ASP.NET MVC 范例应用程序的过程。
&lt;div style="text-align: center"&gt;&lt;img alt="" width="125" height="164" src="/userfiles/entlibforum/image/ebook/Pro_ASP_NET_MVC_Framework_ebook.gif" /&gt;&lt;/div&gt;
&lt;div style="text-align: left"&gt;免费下载地址（pdf 格式）：&lt;br /&gt;
&lt;a href="http://www.apress.com/book/downloadfile/4358"&gt;http://www.apress.com/book/downloadfile/4358&lt;/a&gt;&lt;br /&gt;
 &lt;br /&gt;
该章的范例程序运行界面及范例程序下载：&lt;/div&gt;
&lt;div style="text-align: center"&gt; &lt;img width="510" height="455" alt="" src="/userfiles/entlibforum/image/MVC4/Pro_ASP_NET_MVC_Framework_1.gif" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;img width="466" height="570" alt="" src="/userfiles/entlibforum/image/MVC4/Pro_ASP_NET_MVC_Framework_2.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/189.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>一步一步学习ASP.NET MVC 1.0创建NerdDinner 范例程序，Part 29</title><link>http://blog.entlib.com/entlibforum/archive/2009/04/16/asp.net-mvc-1.0nerddinner-part-29.aspx</link><pubDate>Wed, 15 Apr 2009 22:16:06 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/04/16/asp.net-mvc-1.0nerddinner-part-29.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/188.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/188.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/04/16/asp.net-mvc-1.0nerddinner-part-29.aspx#comment</comments><slash:comments>18</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/188.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">一步一步学习ASP.NET MVC 1.0创建NerdDinner 范例程序，Part 29</source><description>&lt;div align="center"&gt;&lt;b&gt;一步一步学习ASP.NET MVC 1.0&lt;/b&gt;&lt;b&gt;创建NerdDinner &lt;/b&gt;&lt;b&gt;范例程序，Part 29&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文根据《Professional ASP.NET MVC 1.0》中微软牛人Scott Guthrie 提供免费下载的第一章，一步一步演示如何通过ASP.NET MVC 1.0 正式版创建NerdDinner 范例程序。对了解如何使用最新的ASP.NET MVC 1.0框架创建Web Application 非常有帮助。本文由&lt;a href="http://forum.entlib.com/"&gt;http://forum.entlib.com&lt;/a&gt; 开源论坛小组提供。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;前一篇文章：&lt;a href="http://blog.entlib.com/entlibforum/archive/2009/04/15/asp.net-mvc-1.0nerddinner-part-28.aspx"&gt;&lt;span&gt;&lt;span&gt;一步一步学习&lt;/span&gt;ASP.NET MVC 1.0&lt;span&gt;创建&lt;/span&gt;NerdDinner &lt;span&gt;范例程序，&lt;/span&gt;Part 28&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;本文继续学习之旅，一步一步通过ASP.NET MVC 1.0 实现NerdDinner 范例程序。恭喜恭喜，本文终于是本系列文章的最后一篇了。在此，感谢 &lt;b&gt;&lt;span&gt;美女程序员&lt;/span&gt;&lt;/b&gt;、&lt;b&gt;Jacky &lt;/b&gt;的友情协助。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;创建Edit Action&lt;/b&gt;&lt;b&gt;方法的单元测试&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;下面创建DinnersController的编辑功能的单元测试。首先，测试Edit Action方法的HTTP-GET版本：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: green"&gt;//&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: green"&gt;// GET: /Dinners/Edit/2&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ActionResult&lt;/span&gt; Edit(&lt;span style="color: blue"&gt;int&lt;/span&gt; id)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt; dinner = dinnerRepository.GetDinner(id);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (!dinner.IsHostedBy(User.Identity.Name))&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt; View(&lt;span style="color: #a31515"&gt;"InvalidOwner"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// &lt;/span&gt;&lt;/span&gt;&lt;span style="color: green; font-size: 9pt"&gt;使用ViewData&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// ViewData["Countries"] = new SelectList(PhoneValidator.Countries, dinner.Country);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// return View(dinner);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// &lt;/span&gt;&lt;/span&gt;&lt;span style="color: green; font-size: 9pt"&gt;使用ViewModel&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;return&lt;/span&gt; View(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DinnerFormViewModel&lt;/span&gt;(dinner));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;备注：上述代码中DinnerFormViewModel是之前我们定义的一个Model类。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;我们将创建一个测试：当请求一个有效的Dinner对象时，验证返回的DinnerFormViewModel对象。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; EditAction_Should_Return_View_For_ValidDinner()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Arrage&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; controller = CreateDinnersController();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Act&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; result = controller.Edit(2) &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ViewResult&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Assert&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsInstanceOfType(result.ViewData.Model, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;DinnerFormViewModel&lt;/span&gt;));&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;如果现在运行测试，发现测试会失败，这是因为Edit方法在访问User.Identity.Name属性，执行Dinner.IsHostedBy()检查时，抛出null引用异常。&lt;/div&gt;
&lt;div&gt;Controller基类的User对象封装了登录用户的详细信息，在运行时创建Controller时，ASP.NET MVC填充该对象。因为我们测试DinnersController时，没有运行在web-server的环境，因此User 对象没有设置，导致null引用异常。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;模仿User.Identity.Name&lt;/b&gt;&lt;b&gt;属性&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Mocking Framework可以帮忙我们动态创建虚假的依赖对象，支持测试工作。例如，在Edit Action 方法的测试中，我们可以使用一个Mocking Framework，动态创建User对象，DinnersController 将使用该对象来模拟一个用户名。这样在运行测试时，可以避免null引用的发生。&lt;/div&gt;
&lt;div&gt;有很多.NET Mocking Framework可以应用于ASP.NET MVC，访问&lt;a href="http://www.mockframeworks.com/"&gt;&lt;span style="color: windowtext; text-decoration: none; text-underline: none"&gt;http://www.mockframeworks.com&lt;/span&gt;可以查看到。对于NerdDinner 应用程序的测试，我们使用一个开源的Mocking Framework – Moq，可以从如下地址免费下载：&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.mockframeworks.com/moq"&gt;&lt;font color="#0000ff"&gt;http://www.mockframeworks.com/moq&lt;/font&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下载后，在NerdDinner.Tests项目中添加对Moq.dll 程序集的引用。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="500" height="563" src="/userfiles/entlibforum/image/MVC3/MVC_NerdDinner_29_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;接着在测试类中添加一个重载的CreateDinnersControllerAs(username) 辅助方法，接收username参数，该参数模仿DinnersController实例中的User.Identity.Name 属性。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: #2b91af"&gt;DinnersController&lt;/span&gt; CreateDinnersControllerAs(&lt;span style="color: blue"&gt;string&lt;/span&gt; userName)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; mock = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;ControllerContext&lt;/span&gt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            mock.SetupGet(p =&amp;gt; p.HttpContext.User.Identity.Name).Returns(userName);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            mock.SetupGet(p =&amp;gt; p.HttpContext.Request.IsAuthenticated).Returns(&lt;span style="color: blue"&gt;true&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; controller = CreateDinnersController();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            controller.ControllerContext = mock.Object;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;return&lt;/span&gt; controller;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;上述代码使用Moq创建一个Mock对象，虚拟一个ControllerContext对象（该对象是ASP.NET MVC传递给Controller类，公布运行时对象，如User、Request、Response和Session）。调用Mock的SetupGet方法，表示ControllerContext的HttpContext.User.Identity.Name 属性应该返回username字符串，该字符串是传递给辅助方法的参数。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;我们可以模拟ControllerContext的任何属性和方法。为了证明这一点，我们也向Request.IsAuthenticated 属性添加了SetupGet() 的调用（该属性对于下面的测试是不需要的，但是可以证明如何模拟Request属性）。最后，将模拟的ControllerContext实例赋值给辅助方法需要返回DinnersController对象。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面使用上述辅助方法编写单元测试，用不同的用户测试Edit方法：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; EditAction_Should_Return_View_For_ValidDinner()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Arrage&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; controller = CreateDinnersControllerAs(&lt;span style="color: #a31515"&gt;"EntLib.com"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Act&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; result = controller.Edit(2) &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ViewResult&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Assert&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsInstanceOfType(result.ViewData.Model, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;DinnerFormViewModel&lt;/span&gt;));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; EditAction_Should_Return_InvalidOwnerView_When_InvalidOwner()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Arrange&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; controller = CreateDinnersControllerAs(&lt;span style="color: #a31515"&gt;"NotOwnerUser"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Act&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; result = controller.Edit(2) &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ViewResult&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Assert&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(result.ViewName, &lt;span style="color: #a31515"&gt;"InvalidOwner"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;现在通过所有测试：&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="630" height="217" src="/userfiles/entlibforum/image/MVC3/MVC_NerdDinner_29_2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;测试UpdateModel()&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;我们已经创建了测试HTTP-GET版本的Edit Action方法，下面继续创建测试HTTP-POST版本的Edit Action方法：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: green"&gt;//&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: green"&gt;// POST: /Dinners/Edit/2&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;AcceptVerbs&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;HttpVerbs&lt;/span&gt;.Post)]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ActionResult&lt;/span&gt; Edit(&lt;span style="color: blue"&gt;int&lt;/span&gt; id, &lt;span style="color: #2b91af"&gt;FormCollection&lt;/span&gt; formValues) &lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt; dinner = dinnerRepository.GetDinner(id);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (!dinner.IsHostedBy(User.Identity.Name))&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt; View(&lt;span style="color: #a31515"&gt;"InvalidOwner"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;try&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                UpdateModel(dinner);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                dinnerRepository.Save();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt; RedirectToAction(&lt;span style="color: #a31515"&gt;"Details"&lt;/span&gt;, &lt;span style="color: blue"&gt;new&lt;/span&gt; { id = dinner.DinnerID });&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;catch&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                ModelState.AddRuleViolations(dinner.GetRuleViolations());&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: green"&gt;// &lt;/span&gt;&lt;/span&gt;&lt;span style="color: green; font-size: 9pt"&gt;使用ViewData&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: green"&gt;// ViewData["countries"] = new SelectList(PhoneValidator.Countries, dinner.Country);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: green"&gt;// return View(dinner);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: green"&gt;// &lt;/span&gt;&lt;/span&gt;&lt;span style="color: green; font-size: 9pt"&gt;使用ViewModel&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt; View(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DinnerFormViewModel&lt;/span&gt;(dinner));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;上述Action方法使用了Controller基类的UpdateModel() 辅助方法，使用该辅助方法绑定表单提交的值到Dinner对象实例。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面的2个测试演示了如何提供表单提交的值给UpdateModel() 辅助方法使用。通过创建和填充一个FormCollection对象，接着赋值给Controller的ValueProvider属性，来实现测试。测试方法代码如下：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; EditAction_Should_Redirect_When_Update_Successful()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Arrange&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; controller = CreateDinnersControllerAs(&lt;span style="color: #a31515"&gt;"EntLib.com"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; formValues = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;FormCollection&lt;/span&gt;() {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            { &lt;span style="color: #a31515"&gt;"Title"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"Another value"&lt;/span&gt; },&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            { &lt;span style="color: #a31515"&gt;"Description"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"Another description"&lt;/span&gt; }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            };&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            controller.ValueProvider = formValues.ToValueProvider();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Act&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; result = controller.Edit(1, formValues) &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;RedirectToRouteResult&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Assert&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;"Details"&lt;/span&gt;, result.RouteValues[&lt;span style="color: #a31515"&gt;"Action"&lt;/span&gt;]);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; EditAction_Should_Redisplay_With_Errors_When_Update_Fails()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Arrange&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; controller = CreateDinnersControllerAs(&lt;span style="color: #a31515"&gt;"EntLib.com"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; formValues = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;FormCollection&lt;/span&gt;() {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            { &lt;span style="color: #a31515"&gt;"EventDate"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"Bogus date value!!!"&lt;/span&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                            };&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            controller.ValueProvider = formValues.ToValueProvider();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Act&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; result = controller.Edit(1, formValues) &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ViewResult&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Assert&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsNotNull(result, &lt;span style="color: #a31515"&gt;"Expected redisplay of view"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsTrue(result.ViewData.ModelState.Count &amp;gt; 0, &lt;span style="color: #a31515"&gt;"Expected errors"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;其中第一个测试验证：当成功保存后，浏览器重定向到Details Action方法。第二个测试验证：当提交无效的表单参数值时，重新显示带错误消息的Edit视图。现在，再次运行测试，结果如下：&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="629" height="273" src="/userfiles/entlibforum/image/MVC3/MVC_NerdDinner_29_3.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;单元测试总结&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;我们已经完成了对Controller类进行单元测试的核心概念。我们可以使用这些技术轻松创建好几百简单测试，验证应用程序的功能。&lt;/div&gt;
&lt;div&gt;因为Controller和Model测试不需要真实的数据库，这样可以非常快和容易运行。我们可以在几秒钟执行几百个自动化测试，并立即获得信息 – 是否更新破坏了现有的逻辑。这样，让我们有信心持续改进、重构和优化应用程序。&lt;/div&gt;
&lt;div&gt;在本章的最后部分，我们介绍了测试相关技术，但并不表示测试是开发流程的最后阶段。相反，你应该在开发流程中尽早编写自动化测试。这样，你可以在开发过程中及时得到反馈结果，帮助你仔细思考应用程序的业务场景，并指导你设计清晰分层的、松耦合的应用程序。&lt;/div&gt;
&lt;div&gt;《Professional ASP.NET MVC 1.0》这本书的随后章节将介绍Test Driven Development（TDD），已经如何在ASP.NET MVC中使用。TDD是一个迭代的开发过程。通过TDD，首先编写验证将要实现的业务功能的测试。编写单元测试，可以帮助你清晰理解功能和如何工作。仅仅在完成测试代码的编写之后，才可是实现对应的实际功能。因为你已经思考了这些功能如何工作的业务场景，你可以更好地理解需求，以及如何最好地实现。当你完成了业务代码的编写之后，你可以重新运行测试，立即获得关于功能是否工作正常的反馈。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;NerdDinner&lt;/b&gt;&lt;b&gt;范例程序总结&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;NerdDinner范例应用程序终于完成了，已经可以发布了。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="681" height="525" src="/userfiles/entlibforum/image/MVC3/MVC_NerdDinner_29_4.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;我们使用了大量的ASP.NET MVC功能来创建NerdDinner范例程序。希望这一开发过程演示了ASP.NET MVC核心功能是如何工作的，已经如何在一个应用程序中集成这些功能。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/188.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>一步一步学习ASP.NET MVC 1.0创建NerdDinner 范例程序，Part 28</title><link>http://blog.entlib.com/entlibforum/archive/2009/04/15/asp.net-mvc-1.0nerddinner-part-28.aspx</link><pubDate>Tue, 14 Apr 2009 21:37:12 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/04/15/asp.net-mvc-1.0nerddinner-part-28.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/187.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/187.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/04/15/asp.net-mvc-1.0nerddinner-part-28.aspx#comment</comments><slash:comments>9</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/187.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">一步一步学习ASP.NET MVC 1.0创建NerdDinner 范例程序，Part 28</source><description>&lt;div align="center"&gt;&lt;b&gt;一步一步学习ASP.NET MVC 1.0&lt;/b&gt;&lt;b&gt;创建NerdDinner &lt;/b&gt;&lt;b&gt;范例程序，Part 28&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文根据《Professional ASP.NET MVC 1.0》中微软牛人Scott Guthrie 提供免费下载的第一章，一步一步演示如何通过ASP.NET MVC 1.0 正式版创建NerdDinner 范例程序。对了解如何使用最新的ASP.NET MVC 1.0框架创建Web Application 非常有帮助。本文由&lt;a href="http://forum.entlib.com/"&gt;http://forum.entlib.com&lt;/a&gt; 开源论坛小组提供。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;前一篇文章：&lt;a href="http://blog.entlib.com/entlibforum/archive/2009/04/12/asp.net-mvc-1.0nerddinner-part-27.aspx"&gt;&lt;span&gt;&lt;span&gt;一步一步学习&lt;/span&gt;ASP.NET MVC 1.0&lt;span&gt;创建&lt;/span&gt;NerdDinner &lt;span&gt;范例程序，&lt;/span&gt;Part 27&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;本文继续学习之旅，一步一步通过ASP.NET MVC 1.0 实现NerdDinner 范例程序。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;依赖注入（Dependency Injection&lt;/b&gt;&lt;b&gt;）&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;现在DinnersController紧耦合DinnerRepository类，耦合（Coupling）指一个类显式依赖另外的一个类才能工作。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DinnersController&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;Controller&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: #2b91af"&gt;DinnerRepository&lt;/span&gt; dinnerRepository = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DinnerRepository&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: green"&gt;//&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: green"&gt;// GET: /Dinners/Details/2&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ActionResult&lt;/span&gt; Details(&lt;span style="color: blue"&gt;int&lt;/span&gt; id)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt; dinner = dinnerRepository.GetDinner(id);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (dinner == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt; View(&lt;span style="color: #a31515"&gt;"NotFound"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;return&lt;/span&gt; View(&lt;span style="color: #a31515"&gt;"Details"&lt;/span&gt;, dinner);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;因为DinnerRepository 类需要访问数据库，DinnersController类对DinnerRepository类的紧耦合导致DinnersController action方法的测试都需要连接数据库。&lt;/div&gt;
&lt;div&gt;我们可以通过Dependency Injection(依赖注入)设计模式来解决这一问题，类之间（如Repository类提供数据访问）不再创建隐式的依赖。而是，通过调用方的构造函数的参数，显式传递依赖关系。如果依赖关系通过接口来定义，我们就可以针对单元测试的情况，灵活传递虚假（Fake）的依赖实现。这样，我们在创建测试相关的依赖实现时，不必访问真实的数据库。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面演示具体实现，首先对DinnersController实现依赖注入。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;提取IDinnerRepository&lt;/b&gt;&lt;b&gt;接口&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;第一步是创建新的IDinnerRepository接口，封装Controller检索和更新Dinners对象所需要的Repository契约。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;右键点击\Models文件夹，选择 Add-&amp;gt;New Item菜单项，创建一个新的接口IDinnerRepository.cs。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;另外一种方法是，使用Visual Studio 内置的重构工具（Refactoring tools），从现有的DinnerRepository类中自动提取并创建一个接口文件。如通过VS 提取这一接口文件，只需将光标定位到DinnerRepository 类中，右键并选择Refactor -&amp;gt; Extract Interface 菜单项：&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="567" height="394" src="/userfiles/entlibforum/image/MVC3/MVC_NerdDinner_28_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;随后，将弹出Extract Interface 对话框，接口命名默认为IDinnerRepository，并自动选择DinnerRepository类中的所有公共的方法，添加到接口中：&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="473" height="424" src="/userfiles/entlibforum/image/MVC3/MVC_NerdDinner_28_2.gif" /&gt;&lt;br /&gt;
 &lt;/div&gt;
&lt;div&gt;在点击OK按钮后，Visual Studio 将添加一个新的IDinnerRepository接口到应用程序中：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;interface&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IDinnerRepository&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;void&lt;/span&gt; Add(&lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt; dinner);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;void&lt;/span&gt; Delete(&lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt; dinner);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        System.Linq.&lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt;&amp;gt; FindAllDinners();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        System.Linq.&lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt;&amp;gt; FindUpcomingDinners();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt; GetDinner(&lt;span style="color: blue"&gt;int&lt;/span&gt; id);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;void&lt;/span&gt; Save();&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;    }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;现有的DinnerRepository 类将更新为实现该接口：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 10pt"&gt;public class &lt;/span&gt;&lt;span style="color: #2b92b0; font-size: 10pt"&gt;DinnerRepository &lt;/span&gt;&lt;span style="color: black; font-size: 10pt"&gt;: &lt;/span&gt;&lt;span style="color: #2b92b0; font-size: 10pt"&gt;IDinnerRepository &lt;/span&gt;&lt;span style="color: black; font-size: 10pt"&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left; text-indent: 21pt" align="left"&gt;&lt;span style="color: black; font-size: 10pt"&gt;...&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: black; font-size: 10pt"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;更新DinnersController&lt;/b&gt;&lt;b&gt;支持构造器注入&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;现在实现新的接口，更新DinnersController类。&lt;/div&gt;
&lt;div&gt;目前，DinnersController 类是硬编码的，如dinnerRepository属性总是类型为DinnerRepository 实例：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 10pt"&gt;public class &lt;/span&gt;&lt;span style="color: #2b92b0; font-size: 10pt"&gt;DinnersController &lt;/span&gt;&lt;span style="color: black; font-size: 10pt"&gt;: &lt;/span&gt;&lt;span style="color: #2b92b0; font-size: 10pt"&gt;Controller &lt;/span&gt;&lt;span style="color: black; font-size: 10pt"&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left; margin: 0cm 0cm 0pt 10.5pt" align="left"&gt;&lt;span style="color: #2b92b0; font-size: 10pt"&gt;DinnerRepository &lt;/span&gt;&lt;span style="color: black; font-size: 10pt"&gt;dinnerRepository = &lt;/span&gt;&lt;span style="color: blue; font-size: 10pt"&gt;new &lt;/span&gt;&lt;span style="color: #2b92b0; font-size: 10pt"&gt;DinnerRepository&lt;/span&gt;&lt;span style="color: black; font-size: 10pt"&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left; margin: 0cm 0cm 0pt 10.5pt" align="left"&gt;&lt;span style="color: black; font-size: 10pt"&gt;...&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: black; font-size: 10pt"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;我们更改上述代码，将dinnerRepository 属性由DinnerRespository 类型更改为 IDinnerRepository接口类型，接着添加2个公共的DinnersController构造器。其中一个构造器允许传入IDinnerRepository 类型的参数，另外一个是默认的构造器，使用现有的DinnerRepository的实现：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 10pt"&gt;public class &lt;/span&gt;&lt;span style="color: #2b92b0; font-size: 10pt"&gt;DinnersController &lt;/span&gt;&lt;span style="color: black; font-size: 10pt"&gt;: &lt;/span&gt;&lt;span style="color: #2b92b0; font-size: 10pt"&gt;Controller &lt;/span&gt;&lt;span style="color: black; font-size: 10pt"&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left; margin: 0cm 0cm 0pt 21pt" align="left"&gt;&lt;span style="color: #2b92b0; font-size: 10pt"&gt;IDinnerRepository &lt;/span&gt;&lt;span style="color: black; font-size: 10pt"&gt;dinnerRepository;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left; margin: 0cm 0cm 0pt 21pt" align="left"&gt; &lt;/div&gt;
&lt;div style="text-align: left; margin: 0cm 0cm 0pt 21pt" align="left"&gt;&lt;span style="color: blue; font-size: 10pt"&gt;public &lt;/span&gt;&lt;span style="color: black; font-size: 10pt"&gt;DinnersController()&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left; text-indent: 10.5pt; margin: 0cm 0cm 0pt 21pt" align="left"&gt;&lt;span style="color: black; font-size: 10pt"&gt;: &lt;/span&gt;&lt;span style="color: blue; font-size: 10pt"&gt;this&lt;/span&gt;&lt;span style="color: black; font-size: 10pt"&gt;(&lt;/span&gt;&lt;span style="color: blue; font-size: 10pt"&gt;new &lt;/span&gt;&lt;span style="color: #2b92b0; font-size: 10pt"&gt;DinnerRepository&lt;/span&gt;&lt;span style="color: black; font-size: 10pt"&gt;()) {&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left; margin: 0cm 0cm 0pt 21pt" align="left"&gt; &lt;/div&gt;
&lt;div style="text-align: left; margin: 0cm 0cm 0pt 21pt" align="left"&gt;&lt;span style="color: black; font-size: 10pt"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left; margin: 0cm 0cm 0pt 21pt" align="left"&gt;&lt;span style="color: blue; font-size: 10pt"&gt;public &lt;/span&gt;&lt;span style="color: black; font-size: 10pt"&gt;DinnersController(&lt;/span&gt;&lt;b&gt;&lt;span style="color: #2b92b0; font-size: 10pt"&gt;IDinnerRepository &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="color: black; font-size: 10pt"&gt;repository&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-size: 10pt"&gt;) {&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left; text-indent: 10.5pt; margin: 0cm 0cm 0pt 21pt" align="left"&gt;&lt;span style="color: black; font-size: 10pt"&gt;dinnerRepository = repository;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left; margin: 0cm 0cm 0pt 21pt" align="left"&gt;&lt;span style="color: black; font-size: 10pt"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left; margin: 0cm 0cm 0pt 21pt" align="left"&gt;&lt;span style="color: black; font-size: 10pt"&gt;...&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: black; font-size: 10pt"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;因为默认情况下ASP.NET MVC使用默认构造器创建控制器Controller类，DinnersController控制器在运行时将继续使用DinnerRepository类执行数据访问。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;但是，现在我们可以更新单元测试代码，使用带参数的构造器，传入一个虚假的Dinner Repository的实现。虚假的Dinner repository 不需要访问真实的数据库，而是使用内存中的样本数据。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;创建 FakeDinnerRepository &lt;/b&gt;&lt;b&gt;类&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;下面开始创建FakeDinnerRepository类。&lt;/div&gt;
&lt;div&gt;首先，在 NerdDinner.Tests项目中创建Fakes目录，接着添加一个新的FakeDinnerRepository类到该目录（右键点击该目录，选择Add-&amp;gt;New Class菜单项）。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="500" height="386" src="/userfiles/entlibforum/image/MVC3/MVC_NerdDinner_28_3.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;更新FakeDinnerRepository 类，实现IDinnerRepository 接口。接着右键点击，并选择Implement interface IDinnerRepository 上下文菜单项：&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="685" height="400" src="/userfiles/entlibforum/image/MVC3/MVC_NerdDinner_28_4.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;这样，Visual Studio 将自动添加IDinnerRepository 接口成员到FakeDinnerRepository 类中，并附有默认的基础（存根）实现：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;FakeDinnerRepository&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;IDinnerRepository&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;        #region&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; IDinnerRepository Members&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Add(&lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt; dinner)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;NotImplementedException&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Delete(&lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt; dinner)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;NotImplementedException&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt;&amp;gt; FindAllDinners()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;NotImplementedException&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt;&amp;gt; FindUpcomingDinners()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;NotImplementedException&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt; GetDinner(&lt;span style="color: blue"&gt;int&lt;/span&gt; id)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;NotImplementedException&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Save()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;NotImplementedException&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;        #endregion&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;    }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;接着更新FakeDinnerRepository 的实现代码，对作为构造函数参数传入的List&amp;lt;Dinner&amp;gt;集合进行访问，而不是真实的数据库记录：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;   &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;FakeDinnerRepository&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;IDinnerRepository&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt;&amp;gt; dinnerList;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; FakeDinnerRepository(&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt;&amp;gt; dinners)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            dinnerList = dinners;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Add(&lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt; dinner)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            dinnerList.Add(dinner);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Delete(&lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt; dinner)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            dinnerList.Remove(dinner);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt;&amp;gt; FindAllDinners()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;return&lt;/span&gt; dinnerList.AsQueryable();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt;&amp;gt; FindUpcomingDinners()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;return&lt;/span&gt; (&lt;span style="color: blue"&gt;from&lt;/span&gt; dinner &lt;span style="color: blue"&gt;in&lt;/span&gt; dinnerList&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: blue"&gt;where&lt;/span&gt; dinner.EventDate &amp;gt; &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: blue"&gt;select&lt;/span&gt; dinner).AsQueryable();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt; GetDinner(&lt;span style="color: blue"&gt;int&lt;/span&gt; id)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;return&lt;/span&gt; dinnerList.SingleOrDefault(d =&amp;gt; d.DinnerID == id);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Save()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt; dinner &lt;span style="color: blue"&gt;in&lt;/span&gt; dinnerList)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: blue"&gt;if&lt;/span&gt; (!dinner.IsValid)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ApplicationException&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"Rule violations"&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;    }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;现在，虚假的IDinnerRepository 的实现不需要数据库了，可以工作在内存中的Dinner对象列表。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;在单元测试中使用FakeDinnerRepository&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;我们回到DinnersController单元测试，之前由于数据库不能访问，而有异常或失败。在DinnersController类中，我们将使用填充了内存中范例Dinner数据的FakeDinnerRepository 类，来更新测试方法。示例代码如下：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; Summary description for DinnersControllerTest&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    [&lt;span style="color: #2b91af"&gt;TestClass&lt;/span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DinnersControllerTest&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;    {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt;&amp;gt; CreateTestDinners()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt;&amp;gt; dinners = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt;&amp;gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;for&lt;/span&gt; (&lt;span style="color: blue"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 101; i++)&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                &lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt; sampleDinner = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Dinner&lt;/span&gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    DinnerID = i,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    Title = &lt;span style="color: #a31515"&gt;"EntLib.com &lt;/span&gt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;欢迎你"&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    HostedBy = &lt;span style="color: #a31515"&gt;"EntLib.com"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    Address = &lt;span style="color: #a31515"&gt;"http://blog.EntLib.com"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    Country = &lt;span style="color: #a31515"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #a31515; font-size: 9pt"&gt;中国"&lt;/span&gt;&lt;span style="font-size: 9pt"&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    ContactPhone = &lt;span style="color: #a31515"&gt;"12345678"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    Description = &lt;span style="color: #a31515"&gt;"Some description"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    EventDate = &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now.AddDays(i),&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    Latitude = 99,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                    Longitude = -99&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                };&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;                dinners.Add(sampleDinner);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;return&lt;/span&gt; dinners;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: #2b91af"&gt;DinnersController&lt;/span&gt; CreateDinnersController()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; repository = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;FakeDinnerRepository&lt;/span&gt;(CreateTestDinners());&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DinnersController&lt;/span&gt;(repository);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; DetailsAction_Should_Return_View_For_ExistingDinner()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Arrange&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; controller = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DinnersController&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Act&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; result = controller.Details(2) &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ViewResult&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Assert&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.IsInstanceOfType(result, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ViewResult&lt;/span&gt;));&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        [&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; DetailsAction_Should_Return_NotFoundView_For_BogusDinner()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Arrange&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; controller = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DinnersController&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Act&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: blue"&gt;var&lt;/span&gt; result = controller.Details(999) &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ViewResult&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: green"&gt;// Assert&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: #a31515"&gt;"NotFound"&lt;/span&gt;, result.ViewName);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt"&gt;    }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;注意：上述类需要引用如下的namespace：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; NerdDinner.Controllers;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; NerdDinner.Models;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="color: blue; font-size: 9pt"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt"&gt; NerdDinner.Tests.Fakes;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;现在我们运行这些测试方法时，均验证通过：&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center"&gt;&lt;img alt="" width="651" height="171" src="/userfiles/entlibforum/image/MVC3/MVC_NerdDinner_28_5.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;最大的好处是，运行这些测试仅仅需要不到1秒，并且不需要任何复杂的安装/清理逻辑。现在，我们可以单元测试DinnersController类中的所有action方法（包括列表、分页、详细信息、创建、更新和删除等等），而不需要连接真实的数据库。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;a href="http://forum.entlib.com/"&gt;http://forum.EntLib.com&lt;/a&gt; 开源小组备注：NerdDinner 范例程序中使用了Repository Pattern模式，下面进行一些简单的描述，欢迎交流。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;Repository Pattern &lt;/b&gt;&lt;b&gt;的英文解释：&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;原文：http://martinfowler.com/eaaCatalog/repository.html&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面我简单翻译了一下，仅供参考：&lt;/div&gt;
&lt;div&gt;Repository 是位于业务领域层和数据映射层之间协调者，就像一个内存中的业务对象集合。客户端对象清楚地构造查询语句，并提交给Repository执行。业务对象可以添加或从Repository中删除，就像对一个简单集合对象的操作一样，Repository封装的映射代码负责执行后台的正确操作。&lt;/div&gt;
&lt;div&gt;从概念上而言，Repository 封装了持久化业务对象到数据库，以及针对Repository的操作方法，提供了持久层更加面向对象的视图。Repository 也支持实现业务领域层和数据映射层之间的清晰隔离和单向依赖。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;关于&lt;b&gt;Dependency Injection&lt;/b&gt;&lt;b&gt;（依赖注入）&lt;/b&gt;，可以参考学习Enterprise Library 小组的Unity Application Block：&lt;/div&gt;
&lt;div&gt;&lt;a href="http://forum.entlib.com/Default.aspx?g=posts&amp;amp;t=478"&gt;&lt;font color="#0000ff"&gt;Enterprise Library for .NET Framework 3.5 (EntLib v4.1) &lt;span&gt;&lt;span&gt;微软企业库&lt;/span&gt;v4.1&lt;span&gt;实验手册发布啦！&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;img src="http://blog.entlib.com/entlibforum/aggbug/187.aspx" width="1" height="1" /&gt;</description><dc:creator>entlibforum</dc:creator></item><item><title>一步一步学习ASP.NET MVC 1.0创建NerdDinner 范例程序，Part 27</title><link>http://blog.entlib.com/entlibforum/archive/2009/04/12/asp.net-mvc-1.0nerddinner-part-27.aspx</link><pubDate>Sat, 11 Apr 2009 20:19:24 GMT</pubDate><guid isPermaLink="true">http://blog.entlib.com/entlibforum/archive/2009/04/12/asp.net-mvc-1.0nerddinner-part-27.aspx</guid><wfw:comment>http://blog.entlib.com/entlibforum/comments/186.aspx</wfw:comment><wfw:commentRss>http://blog.entlib.com/entlibforum/comments/commentRss/186.aspx</wfw:commentRss><comments>http://blog.entlib.com/entlibforum/archive/2009/04/12/asp.net-mvc-1.0nerddinner-part-27.aspx#comment</comments><slash:comments>7</slash:comments><trackback:ping>http://blog.entlib.com/entlibforum/services/trackbacks/186.aspx</trackback:ping><source url="http://blog.entlib.com/entlibforum/rss.aspx">一步一步学习ASP.NET MVC 1.0创建NerdDinner 范例程序，Part 27</source><description>&lt;div align="center"&gt;&lt;b&gt;一步一步学习ASP.NET MVC 1.0&lt;/b&gt;&lt;b&gt;创建NerdDinner &lt;/b&gt;&lt;b&gt;范例程序，Part 27&lt;/b&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;本文根据《Professional ASP.NET MVC 1.0》中微软牛人Scott Guthrie 提供免费下载的第一章，一步一步演示如何通过ASP.NET MVC 1.0 正式版创建NerdDinner 范例程序。对了解如何使用最新的ASP.NET MVC 1.0框架创建Web Application 非常有帮助。本文由&lt;a href="http://forum.entlib.com/"&gt;http://forum.entlib.com&lt;/a&gt; 开源论坛小组提供。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;前一篇文章：&lt;a href="http://blog.entlib.com/entlibforum/archive/2009/04/11/asp.net-mvc-1.0nerddinner-part-26.aspx"&gt;&lt;span&gt;&lt;span&gt;一步一步学习&lt;/span&gt;ASP.NET MVC 1.0&lt;span&gt;创建&lt;/span&gt;NerdDinner &lt;span&gt;范例程序，&lt;/span&gt;Part 26&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;本文继续学习之旅，一步一步通过ASP.NET MVC 1.0 实现NerdDinner 范例程序。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;单元测试&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;让我们开发一套自动的单元测试来验证NerdDinner范例程序的功能，这样在将来，我们可以自信地修改和改进应用程序。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;为什么需要单元测试？&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;某天早上，你突然灵光一现，对正在工作的应用程序有个新的想法。你认为如果你实现一个更新，将是整个应用程序得到极大的改进。这也许就是重构，精简代码、添加新的功能或者修复bug。&lt;/div&gt;
&lt;div&gt;当你坐在电脑前时，你面临的一个问题是 – 做这些更改，到底有多安全？是否这些更新有副作用或者破坏一些功能？这些更新可能很简单，只需要几分钟就可以完成，但是是否需要数个小时来手动测试整个应用程序？是否有可能你忘记一些，并导致有问题的应用程序上线到生产环境？做这些更新是否真的值得所有的付出？&lt;/div&gt;
&lt;div&gt;自动化单元测试提供安全性，让你不断地增强你的应用程序，并避免害怕更新代码。自动化测试快速验证应用程序的功能，让你变得更加自信，有能力改进代码。也有助于创建易于维护和长久生命周期的项目，从而产生更高的投资回报。&lt;/div&gt;
&lt;div&gt;ASP.NET MVC框架使得单元测试更加容易和自然，也支持TDD（Test Driven Development）工作流，开发基于测试优先。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;NerdDinner.Tests &lt;/b&gt;&lt;b&gt;项目&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;当我们在最开始创建NerdDinner范例程序时，会弹出一个对话框询问是否想同时创建单元测试项目。具体细节请参考《&lt;a href="http://blog.entlib.com/entlibforum/archive/2009/03/28/asp.net-mvc-1.0nerddinner-part-1.aspx"&gt;&lt;span&gt;&lt;span&gt;一步一步学习&lt;/span&gt;ASP.NET MVC 1.0&lt;span&gt;创建&lt;/span&gt;NerdDinner &lt;span&gt;范例程序，&lt;/span&gt;Part 1&lt;/span&gt;&lt;/a&gt;》，这里不重复了。&lt;/div&gt;
&lt;div&gt;NerdDinner.Tests项目引用了NerdDinner应用程序项目的程序集，让我们轻松实现自动化测试，并验证应用程序的功能。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;为Dinner&lt;/b&gt;&lt;b&gt;模型类创建单元测试&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;添加一些测试到NerdDinner.Tests项目，验证我们在创建模型层（Model Layer）创建的Dinner类。&lt;/div&gt;
&lt;div&gt;在测试项目创建一个新的文件夹 – Models，在这里我们存放一些模型相关的测试。接着，右键单击文件夹，选择Add-&amp;gt;New Test菜单项，将弹出Add New Test对话框。&lt;/div&gt;
&lt;div&gt;我们选择创建Unit Test单元测试，命名为DinnerTest.cs：&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center;"&gt;&lt;img height="559" width="604" alt="" src="/userfiles/entlibforum/image/MVC3/MVC_NerdDinner_27_1.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;默认Visual Studio 的单元测试模板有一些代码，且有些杂乱。让我们清理代码如下：&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt;"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt;"&gt; System;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt;"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt;"&gt; System.Text;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt;"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt;"&gt; System.Collections.Generic;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt;"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt;"&gt; System.Linq;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt;"&gt;using&lt;/span&gt;&lt;span style="font-size: 9pt;"&gt; Microsoft.VisualStudio.TestTools.UnitTesting;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="color: blue; font-size: 9pt;"&gt;namespace&lt;/span&gt;&lt;span style="font-size: 9pt;"&gt; NerdDinner.Tests.Models&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;    &lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;    &lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; Summary description for DinnerTest&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;    &lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;    [&lt;span style="color: rgb(43, 145, 175);"&gt;TestClass&lt;/span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;    &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;DinnerTest&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;    {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;    }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;DinnerTest类中的[TestClass] 属性标识该类将包含测试，以及可选的初始化和代码。我们可以添加其他公有的方法，并设置 [TestClass] 属性。&lt;/div&gt;
&lt;div&gt;下面是我们测试Dinnerlei的其中第一个（总共有2个）测试，第一个测试验证：如果一个新的Dinner对象创建过程中没有设置正确的属性，测试方法则认为Dinner对象是无效的。&lt;/div&gt;
&lt;div&gt;接下来是第二个测试，该测试验证如果一个Dinner对象正确设置了所有属性，则Dinner对象是有效的。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;    [&lt;span style="color: rgb(43, 145, 175);"&gt;TestClass&lt;/span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;    &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;DinnerTest&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;    {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;        [&lt;span style="color: rgb(43, 145, 175);"&gt;TestMethod&lt;/span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;        &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Dinner_Should_Not_Be_Valid_When_Some_Properties_Incorrect()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            &lt;span style="color: green;"&gt;//Arrange&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            &lt;span style="color: rgb(43, 145, 175);"&gt;Dinner&lt;/span&gt; dinner = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Dinner&lt;/span&gt;()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;                Title = &lt;span style="color: rgb(163, 21, 21);"&gt;"Test title"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;                Country = &lt;span style="color: rgb(163, 21, 21);"&gt;"USA"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;                ContactPhone = &lt;span style="color: rgb(163, 21, 21);"&gt;"BOGUS"&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            };&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            &lt;span style="color: green;"&gt;// Act&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            &lt;span style="color: blue;"&gt;bool&lt;/span&gt; isValid = dinner.IsValid;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            &lt;span style="color: green;"&gt;//Assert&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            &lt;span style="color: rgb(43, 145, 175);"&gt;Assert&lt;/span&gt;.IsFalse(isValid);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt; &lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;        [&lt;span style="color: rgb(43, 145, 175);"&gt;TestMethod&lt;/span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;        &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Dinner_Should_Be_Valid_When_All_Properties_Correct()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            &lt;span style="color: green;"&gt;//Arrange&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            &lt;span style="color: rgb(43, 145, 175);"&gt;Dinner&lt;/span&gt; dinner = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Dinner&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;                Title = &lt;span style="color: rgb(163, 21, 21);"&gt;"Test title"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;                Description = &lt;span style="color: rgb(163, 21, 21);"&gt;"Some description"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;                EventDate = &lt;span style="color: rgb(43, 145, 175);"&gt;DateTime&lt;/span&gt;.Now,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;                HostedBy = &lt;span style="color: rgb(163, 21, 21);"&gt;"ScottGu"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;                Address = &lt;span style="color: rgb(163, 21, 21);"&gt;"One Microsoft Way"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;                Country = &lt;span style="color: rgb(163, 21, 21);"&gt;"USA"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;                ContactPhone = &lt;span style="color: rgb(163, 21, 21);"&gt;"425-703-8072"&lt;/span&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;                Latitude = 93,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;                Longitude = -92,&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            };&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            &lt;span style="color: green;"&gt;// Act&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            &lt;span style="color: blue;"&gt;bool&lt;/span&gt; isValid = dinner.IsValid;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            &lt;span style="color: green;"&gt;//Assert&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            &lt;span style="color: rgb(43, 145, 175);"&gt;Assert&lt;/span&gt;.IsTrue(isValid);&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;        }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style="font-size: 9pt;"&gt;    }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;你应该注意到测试方法的名称非常清楚（甚至有点冗长）。我们这样命名是因为我们需要创建成千上百的测试方法，通过方法名称，我们可以迅速地了解的每一个方法的意图和行为（特别是在查看错误列表时）。测试方法的名称总是命名为正在测试的功能，我们使用Noun_Should_Verb 命名模式。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;我们使用AAA测试模式创建测试方法 – 分别代表Arrange、 Act和Assert：&lt;/div&gt;
&lt;div&gt;Arrange – 设置测试单元；&lt;/div&gt;
&lt;div&gt;Act – 执行测试单元，并捕获结果；&lt;/div&gt;
&lt;div&gt;Assert – 验证执行行为；&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;当我们编写测试时，应尽量避免有太多的单个的测试。每一个测试应该验证一个单一的概念（这样，可以轻松定位到错误的原因）。一个好的设计向导是尽量针对每一个测试有一个assert（断言）语句。如果你在一个测试方法中有多个assert语句，确保它们都在测试同一个概念。如不确定，则创建另外一个测试方法。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;运行测试&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;Visual Studio 2008 专业版（或其他高级版本）包含了一个内置的测试运行器，可以在IDE中运行Visual Studio Unit Test项目。选择 Test -&amp;gt; Run -&amp;gt; All Tests in Solution 菜单项，运行所有的单元测试。或者将光标定位到一个特定的测试类或测试方法中，选择 Test -&amp;gt; Run -&amp;gt; Test in Current Context菜单项，运行部分单元测试。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;下面我们将光标定位到DinnerTest类中，选择Test -&amp;gt; Run -&amp;gt; Test in Current Context 菜单项，运行我们刚才定义的2个测试方法。随后Test Results窗口自动在Visual Studio 中出现，我们将可以看到测试结果：&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center;"&gt;&lt;img height="220" width="689" alt="" src="/userfiles/entlibforum/image/MVC3/MVC_NerdDinner_27_2.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;备注：VS 测试结果窗口默认没有显示类名称（Class Name）。可以右键点击Test Results 窗口，选择Add/Remove Columns菜单项，然后添加Class Name选项。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;上述仅仅测试了一小部分，且都通过了测试。下面进行创建其他的测试，来验证特定的规则，并覆盖2个辅助方法 – IsUserHost() 和 IsUserRegistered() – 这是之前添加到Dinner类中的方法。针对Dinner类的这些测试让我们今后可以更容易和更安全地添加新的业务规则和验证。我们可以添加新的业务逻辑到Dinner类中，然后在几秒钟内验证这些更新是否破坏了任何之前的逻辑和功能。&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;认识到一个清楚的测试方法的名称有助于尽快理解政治测试的内容。另外，还建议使用 Tools-&amp;gt;Options 菜单项，打开 Test Tools -&amp;gt; Test Execution 配置窗口，选择“Double-clicking a failed or inconclusive unit test result displays the point of failure in the test”复选框。当在测试结果窗口双击错误记录时，会立即跳到断言错误的地方。&lt;br /&gt;
 &lt;/div&gt;
&lt;div style="text-align: center;"&gt;&lt;img height="448" width="690" alt="" src="/userfiles/entlibforum/image/MVC3/MVC_NerdDinner_27_3.gif" /&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;b&gt;创建DinnersController &lt;/b&gt;&lt;b&gt;单元测试&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;下面创建一个单元测试验证DinnersController 的功能。右键点击测试项目中的Controllers文件夹，选择Add-&amp;gt;New Test 菜单项，创建一个单元测试，命名为DinnersControllerTest.cs。&lt;/div&gt;
&lt;div&gt;创建2个测试方法验证DinnersController中的Details() action方法。第一个将验证当请求一个存在的Dinner对象时，一个视图将返回。第二个将验证如果请求一个不存在的Dinner对象时，NotFound视图将返回。&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;    [&lt;span style="color: rgb(43, 145, 175);"&gt;TestClass&lt;/span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;    &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;DinnersControllerTest&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;    {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;        [&lt;span style="color: rgb(43, 145, 175);"&gt;TestMethod&lt;/span&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;        &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; DetailsAction_Should_Return_View_For_ExistingDinner()&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;        {&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            &lt;span style="color: green;"&gt;// Arrange&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            &lt;span style="color: blue;"&gt;var&lt;/span&gt; controller = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;DinnersController&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            &lt;span style="color: green;"&gt;// Act&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="left"&gt;&lt;span style="font-size: 9pt;"&gt;            &lt;span style="color: blue;"&gt;var&lt;/span&gt; result = controller.Details(2) &lt;span style="color: blue;"&gt;as&lt;/span&gt; &lt;span style="col