﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><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>博客园-TerryLee's Tech Space</title><link>http://www.cnblogs.com/Terrylee/</link><description>TerryLee技术专栏</description><language>zh-cn</language><lastBuildDate>Mon, 06 Jul 2009 05:22:31 GMT</lastBuildDate><pubDate>Mon, 06 Jul 2009 05:22:31 GMT</pubDate><ttl>60</ttl><item><title>ASP.NET MVC Performance Tips(1)：RenderPartial性能优化</title><link>http://www.cnblogs.com/Terrylee/archive/2009/05/08/ASPNET-MVC-Performance-Tips-Part1.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Thu, 07 May 2009 18:11:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2009/05/08/ASPNET-MVC-Performance-Tips-Part1.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1452324.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2009/05/08/ASPNET-MVC-Performance-Tips-Part1.html#Feedback</comments><slash:comments>94</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1452324.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1452324.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_net.png" alt=""/></div>在ASP.NET MVC中，HtmlHelper的扩展方法RenderPartial为我们使用UserControl带来了极大的方便，当我们指定一个UserControl时，RenderPartial会在当前View文件夹下查找相应的UserControl，如果没有找到则会到Shared文件夹下查找。然后在使用RenderPartial方法有一些性能方面的考虑，值得我们去关注。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2009/05/08/ASPNET-MVC-Performance-Tips-Part1.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1452324.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48002/" target="_blank">竞争日趋激烈 微软欲借 Windows 7 扭转战局</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>《Silverlight 2完美征程》：推荐序</title><link>http://www.cnblogs.com/Terrylee/archive/2009/04/23/1442450.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Thu, 23 Apr 2009 13:52:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2009/04/23/1442450.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1442450.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2009/04/23/1442450.html#Feedback</comments><slash:comments>71</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1442450.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1442450.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_silverlight2.gif" alt=""/></div>《Silverlight 2完美征程》就是这样的一本书！在Silverlight 2 Beta1期间就已经成稿，在Silverlight 2 RTW版出来后，Terry又投入了大量的精力来重写和校正。书的内容覆盖了Silverlight 2开发的各个方面并被整理得井井有条，多年的技术写作功底在这里又一次得到了体现：图文并茂、讲解透彻，一如博客园中的TerryLee。<br/>
读过本书之后，我对Terry的第一句话就是，怎么还有这么多我们之前没有谈到的内容？<br/>
我相信，大家读后的收获，一定会比我更多！&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2009/04/23/1442450.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1442450.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48001/" target="_blank">上海电信计划2012年80%用户实现100M带宽</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>《Silverlight 2完美征程》：书稿目录</title><link>http://www.cnblogs.com/Terrylee/archive/2009/04/22/silverlight-travelling-index.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Tue, 21 Apr 2009 19:19:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2009/04/22/silverlight-travelling-index.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1440904.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2009/04/22/silverlight-travelling-index.html#Feedback</comments><slash:comments>59</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1440904.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1440904.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_silverlight2.gif" alt=""/></div>本书详细介绍了微软下一代富互联网开发技术Silverlight，分为基础篇、进阶篇、高级篇和案例篇四个部分，共22个章节，以Silverlight 2为主要版本从不同的层面进行了阐释，第一部分介绍Silverlight 中的基础知识、控件模型以及它在绘图方面的能力；第二部分介绍了Silverlight中丰富的网络通信功能、托管代码与浏览器之间的互操作性以及数据绑定等；第三部分对Silverlight应用程序的生命周期进行剖析，并介绍了一些调试技巧；最后一部分开发了Deep Zoom应用程序和图表应用程序两个案例。全书对每个知识点都通过示例进行讲解，一步一步带您进入Silverlight世界。
详情敬请访问《Silverlight 2完美征程》官方网站：http://www.dotneteye.cn&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2009/04/22/silverlight-travelling-index.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1440904.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48000/" target="_blank">数万名网友签名抗议星际争霸2取消局域网功能</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>技巧：使用可扩展对象模式扩展HttpApplication</title><link>http://www.cnblogs.com/Terrylee/archive/2009/04/20/Using-Extensible-Object-Pattern-to-Extend-HttpApplication.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Sun, 19 Apr 2009 18:28:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2009/04/20/Using-Extensible-Object-Pattern-to-Extend-HttpApplication.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1439394.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2009/04/20/Using-Extensible-Object-Pattern-to-Extend-HttpApplication.html#Feedback</comments><slash:comments>47</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1439394.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1439394.html</trackback:ping><description><![CDATA[<h2>概述</h2>  <p>HttpApplication对象对于做ASP.NET开发的朋友，我想没有人不熟悉它。在ASP.NET开发中，经常避免不了要在HttpApplication中执行一些操作，如使用了ASP.NET MVC框架，就会在Application_Start 事件中避免不了这样的路由规则配置代码：</p>  <pre class="code"><span style="color: blue">protected void </span>Application_Start()
{
    <span style="color: #2b91af">RouteTable</span>.Routes.IgnoreRoute(<span style="color: #a31515">&quot;{resource}.axd/{*pathInfo}&quot;</span>);

    <span style="color: #2b91af">RouteTable</span>.Routes.MapRoute(
        <span style="color: #a31515">&quot;Default&quot;</span>,                                              <span style="color: green">// Route name
        </span><span style="color: #a31515">&quot;{controller}/{action}/{id}&quot;</span>,                           <span style="color: green">// URL with parameters
        </span><span style="color: blue">new </span>{ controller = <span style="color: #a31515">&quot;Home&quot;</span>, action = <span style="color: #a31515">&quot;Index&quot;</span>, id = <span style="color: #a31515">&quot;&quot; </span>}  <span style="color: green">// Parameter defaults
    </span>);
}</pre>
<a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a>

<p>如果仅仅是这一条，看起来倒不觉的有什么问题，但如果同时在应用程序中使用了工作流，又避免不了在Application_Start出现启动工作流运行时的代码：</p>

<pre class="code"><span style="color: blue">protected void </span>Application_Start()
{
    <span style="color: green">// 注册路由规则
    </span><span style="color: #2b91af">RouteTable</span>.Routes.IgnoreRoute(<span style="color: #a31515">&quot;{resource}.axd/{*pathInfo}&quot;</span>);
    <span style="color: #2b91af">RouteTable</span>.Routes.MapRoute(
        <span style="color: #a31515">&quot;Default&quot;</span>,                                              <span style="color: green">// Route name
        </span><span style="color: #a31515">&quot;{controller}/{action}/{id}&quot;</span>,                           <span style="color: green">// URL with parameters
        </span><span style="color: blue">new </span>{ controller = <span style="color: #a31515">&quot;Home&quot;</span>, action = <span style="color: #a31515">&quot;Index&quot;</span>, id = <span style="color: #a31515">&quot;&quot; </span>}  <span style="color: green">// Parameter defaults
    </span>);

    <span style="color: green">// 启动工作流
    </span><span style="color: #2b91af">WorkflowRuntime </span>workflowRuntime = <span style="color: blue">new </span><span style="color: #2b91af">WorkflowRuntime</span>(<span style="color: #a31515">&quot;workflowServicesConfig&quot;</span>);
    <span style="color: #2b91af">ExternalDataExchangeService </span>externalDataExchangeService = <span style="color: blue">new </span><span style="color: #2b91af">ExternalDataExchangeService</span>();
    workflowRuntime.AddService(externalDataExchangeService);
    workflowRuntime.StartRuntime();
}</pre>
<a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a>

<p>试想一下，现在我们仅仅是有了ASP.NET MVC路由规则的配置、WF运行时的启动，如果在应用程序中使用某种DI框架，如微软的Unity，是不是又避免不了要出现这样的容器初始化代码呢？</p>

<pre class="code"><span style="color: blue">protected void </span>Application_Start()
{
    <span style="color: green">// 注册路由规则
    </span><span style="color: #2b91af">RouteTable</span>.Routes.IgnoreRoute(<span style="color: #a31515">&quot;{resource}.axd/{*pathInfo}&quot;</span>);
    <span style="color: #2b91af">RouteTable</span>.Routes.MapRoute(
        <span style="color: #a31515">&quot;Default&quot;</span>,                                              <span style="color: green">// Route name
        </span><span style="color: #a31515">&quot;{controller}/{action}/{id}&quot;</span>,                           <span style="color: green">// URL with parameters
        </span><span style="color: blue">new </span>{ controller = <span style="color: #a31515">&quot;Home&quot;</span>, action = <span style="color: #a31515">&quot;Index&quot;</span>, id = <span style="color: #a31515">&quot;&quot; </span>}  <span style="color: green">// Parameter defaults
    </span>);

    <span style="color: green">// 启动工作流
    </span><span style="color: #2b91af">WorkflowRuntime </span>workflowRuntime = <span style="color: blue">new </span><span style="color: #2b91af">WorkflowRuntime</span>(<span style="color: #a31515">&quot;workflowServicesConfig&quot;</span>);
    <span style="color: #2b91af">ExternalDataExchangeService </span>externalDataExchangeService = <span style="color: blue">new </span><span style="color: #2b91af">ExternalDataExchangeService</span>();
    workflowRuntime.AddService(externalDataExchangeService);
    workflowRuntime.StartRuntime();

    <span style="color: green">// 初始化DI容器
    </span>IContainerContext repositoryContainer = ContainerManager.GetContainer(<span style="color: #a31515">&quot;repositoryContainer&quot;</span>);
    repositoryContainer.Initialize();
}</pre>
<a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a>

<p>再看看Application_Start事件中的代码，有ASP.NET MVC的工作，有WF的工作，也有Unity的工作，不知道将来还会有什么？这些原本互相之间没有任何联系的代码，现在却同时堆在了一起，当每一部分（或者说每一个框架）变化的时候，都会涉及到Application_Start中代码的修改，显然违反了OCP原则。那么有没有一种机制，让这些互不相干的模块之间互相独立，各自发生变化时不影响对HttpApplication？此时我们就需要对HttpApplication进行扩展，提供一个扩展点，让其他模块的程序附加到HttpApplication上面。</p>

<h2>可扩展对象模式</h2>

<p>我们知道WCF提供了非常完美的扩展机制，几乎在服务执行过程中的每一个环节上都提供有扩展点，如ServiceHostBase、OperationContext、InstanceContext、IContextChannel，这些对象都属于可扩展对象，它们都通过Extensions属性获取用于所有扩展的集合。我们能不能使用这种方式对HttpApplication也进行扩展呢，答案自然是肯定的。查阅一下MSDN就会知道在System.ServiceModel命名空间下面提供了这样的一组接口：IExtensibleObject、IExtension和IExtensionCollection，这是可扩展对象模式中最重要的三个接口，也只有这三个接口。</p>

<p>IExtensibleObject自然是定义了可扩展对象，即我们要对谁进行扩展，它的定义非常简单，仅仅是提供了一个只读的属性Extensions，用来提供所有扩展对象的集合，如下代码所示：</p>

<pre class="code"><span style="color: blue">public interface </span><span style="color: #2b91af">IExtensibleObject</span>&lt;T&gt; <span style="color: blue">where </span>T : <span style="color: #2b91af">IExtensibleObject</span>&lt;T&gt;
{
    <span style="color: #2b91af">IExtensionCollection</span>&lt;T&gt; Extensions { <span style="color: blue">get</span>; }
}</pre>
<a href="http://11011.net/software/vspaste"></a>

<p>IExtension定义了扩展对象的契约，使对象可以通过聚合扩展另一个对象（此处的另一个对象，就是指上面所讲的扩展宿主IExtensibleObject），在IExtension中定义了两个非常重要的方法Attach和Detach方法，分别用来提供聚合或解聚的通知。</p>

<pre class="code"><span style="color: blue">public interface </span><span style="color: #2b91af">IExtension</span>&lt;T&gt; <span style="color: blue">where </span>T : <span style="color: #2b91af">IExtensibleObject</span>&lt;T&gt;
{
    <span style="color: blue">void </span>Attach(T owner);
    <span style="color: blue">void </span>Detach(T owner);
}</pre>

<p>当一个扩展对象IExtension附加到可扩展对象的扩展集合中时，它的Attach方法将会被调用；反之如果从集合中移除一个扩展对象时，它的Detach方法会被调用。这一点我们可以通过Reflector来得到验证，如下代码所示：</p>

<pre class="code"><span style="color: blue">protected override void </span>InsertItem(<span style="color: blue">int </span>index, IExtension&lt;T&gt; item)
{
    <span style="color: blue">lock </span>(<span style="color: blue">base</span>.SyncRoot)
    {
        item.Attach(<span style="color: blue">this</span>.owner);
        <span style="color: blue">base</span>.InsertItem(index, item);
    }
}

<span style="color: blue">protected override void </span>RemoveItem(<span style="color: blue">int </span>index)
{
    <span style="color: blue">lock </span>(<span style="color: blue">base</span>.SyncRoot)
    {
        <span style="color: blue">base</span>.Items[index].Detach(<span style="color: blue">this</span>.owner);
        <span style="color: blue">base</span>.RemoveItem(index);
    }
}</pre>

<p>最后一个接口是IExtensionCollection，它是IExtension对象的集合。</p>

<h2>对HttpApplication进行扩展</h2>

<p>下面我们就看一下如何使用可扩展对象模式对HttpApplication进行扩展，首先定义可扩展对象，让ExtensibleHttpApplication派生于HttpApplication，并实现了IExtensibleObject接口，泛型的参数类型就是它自身，如下代码所示：</p>

<pre class="code"><span style="color: blue">public class </span><span style="color: #2b91af">ExtensibleHttpApplication </span>: <span style="color: #2b91af">HttpApplication</span>,
    <span style="color: #2b91af">IExtensibleObject</span>&lt;<span style="color: #2b91af">ExtensibleHttpApplication</span>&gt;
{
    <span style="color: blue">private </span><span style="color: #2b91af">IExtensionCollection</span>&lt;<span style="color: #2b91af">ExtensibleHttpApplication</span>&gt; _extensions;
    
    <span style="color: blue">public </span>ExtensibleHttpApplication()
    {
        <span style="color: blue">this</span>._extensions = <span style="color: blue">new </span><span style="color: #2b91af">ExtensionCollection</span>&lt;<span style="color: #2b91af">ExtensibleHttpApplication</span>&gt;(<span style="color: blue">this</span>);
    }

    <span style="color: blue">public </span><span style="color: #2b91af">IExtensionCollection</span>&lt;<span style="color: #2b91af">ExtensibleHttpApplication</span>&gt; Extensions
    {
        <span style="color: blue">get
        </span>{
            <span style="color: blue">return this</span>._extensions;
        }
    }
}</pre>
<a href="http://11011.net/software/vspaste"></a>

<p>有了可扩展的HttpApplication之后，需要在HttpApplication中实现任何功能，都可以作为一个扩展附加到ExtensibleHttpApplication上去，如实现ASP.NET MVC路由，可以定义一个如下代码所示的扩展对象：</p>

<pre class="code"><span style="color: blue">public class </span><span style="color: #2b91af">MvcHttpApplication </span>: <span style="color: #2b91af">IExtension</span>&lt;<span style="color: #2b91af">ExtensibleHttpApplication</span>&gt;
{
    <span style="color: blue">public void </span>Attach(<span style="color: #2b91af">ExtensibleHttpApplication </span>owner)
    {
        <span style="color: #2b91af">RouteTable</span>.Routes.IgnoreRoute(<span style="color: #a31515">&quot;{resource}.axd/{*pathInfo}&quot;</span>);

        <span style="color: #2b91af">RouteTable</span>.Routes.MapRoute(
            <span style="color: #a31515">&quot;Default&quot;</span>,                                              <span style="color: green">// Route name
            </span><span style="color: #a31515">&quot;{controller}/{action}/{id}&quot;</span>,                           <span style="color: green">// URL with parameters
            </span><span style="color: blue">new </span>{ controller = <span style="color: #a31515">&quot;Home&quot;</span>, action = <span style="color: #a31515">&quot;Index&quot;</span>, id = <span style="color: #a31515">&quot;&quot; </span>}  <span style="color: green">// Parameter defaults
        </span>);
    }

    <span style="color: blue">public void </span>Detach(<span style="color: #2b91af">ExtensibleHttpApplication </span>owner)
    {
        <span style="color: green">//nothing
    </span>}
}</pre>

<p><a href="http://11011.net/software/vspaste"></a>同样如果要在HttpApplication中启动Workflow，可以再针对Workflow定义一个扩展对象，如下示例代码所示：</p>

<pre class="code"><span style="color: blue">public class </span><span style="color: #2b91af">WorkflowHttpApplication </span>: <span style="color: #2b91af">IExtension</span>&lt;<span style="color: #2b91af">ExtensibleHttpApplication</span>&gt;
{
    <span style="color: blue">private </span><span style="color: #2b91af">WorkflowRuntime </span>workflowRuntime;
    <span style="color: blue">public void </span>Attach(<span style="color: #2b91af">ExtensibleHttpApplication </span>owner)
    {
        workflowRuntime = <span style="color: blue">new </span><span style="color: #2b91af">WorkflowRuntime</span>(<span style="color: #a31515">&quot;workflowServicesConfig&quot;</span>);
        <span style="color: #2b91af">ExternalDataExchangeService </span>externalDataExchangeService = <span style="color: blue">new </span><span style="color: #2b91af">ExternalDataExchangeService</span>();
        workflowRuntime.AddService(externalDataExchangeService);
        workflowRuntime.StartRuntime();
    }

    <span style="color: blue">public void </span>Detach(<span style="color: #2b91af">ExtensibleHttpApplication </span>owner)
    {
        workflowRuntime.StopRuntime();
    }
}</pre>
<a href="http://11011.net/software/vspaste"></a>

<p>我们已经定义好了相应的扩展对象，只需要在相应的HttpApplication把扩展对象附加到ExtensibleHttpApplication上即可，修改Global.asax中的代码如下所示：</p>

<pre class="code"><span style="color: blue">public class </span><span style="color: #2b91af">MvcApplication </span>: <span style="color: #2b91af">ExtensibleHttpApplication
</span>{
    <span style="color: blue">protected void </span>Application_Start()
    {
        <span style="color: blue">this</span>.Extensions.Add(<span style="color: blue">new </span><span style="color: #2b91af">MvcHttpApplication</span>());
        <span style="color: blue">this</span>.Extensions.Add(<span style="color: blue">new </span><span style="color: #2b91af">WorkflowHttpApplication</span>());
    }
}</pre>
<a href="http://11011.net/software/vspaste"></a>

<p>现在代码是不是看起来优雅多了？现在如果要在Application_Start中，添加另外一些执行代码，只需要编写相应的扩展对象，并将其添加到Extension集合中即可。也许有朋友会问，这样每添加一些新的代码，还是要修改Application_Start中的代码啊？别忘了，可以通过配置可以解决这个问题，WCF中的扩展不也是可以采用配置方式实现，不是吗？同样，如果我们需要在Application_End事件中释放某些对象，可以直接从扩展集合中移除它，此时将会调用它的Detach方法。</p>

<h2>总结</h2>

<p>本文介绍了如何使用WCF中提供的可扩展对象模式扩展HttpApplication，事实上可扩展对象模式的作用远不在此，它可以扩展.NET类库中任何我们想对其进行扩展的对象，或者是一个自定义的类型，都可以使用可扩展对象模式对其进行扩展。</p>

<p>特别鸣谢：<a href="http://www.cnblogs.com/jessequ">Jesse Qu</a></p>

<p>注1：由于TerryLee最近一段时间忙于别的事务，无暇顾及Blog，所以有大量的评论和E-mail都没能回复，请大家见谅。</p>

<p>注2：由TerryLee撰写的《Silverlight 2完美征程》一书，即将于本月底上市，敬请期待，详情大家可以访问本书官方网站<a href="http://www.dotneteye.cn/silverlight">http://www.dotneteye.cn/silverlight</a>了解。</p><img src ="http://www.cnblogs.com/Terrylee/aggbug/1439394.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47999/" target="_blank">Silverlight打造杰克逊纪念专题</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>代友招聘：软件测试工程师</title><link>http://www.cnblogs.com/Terrylee/archive/2009/01/13/1374557.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Mon, 12 Jan 2009 16:35:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2009/01/13/1374557.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1374557.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2009/01/13/1374557.html#Feedback</comments><slash:comments>32</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1374557.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1374557.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_job.png" alt=""/></div>继上次在园子里帮朋友发了一则招聘启事之后，还是原来的那个项目，朋友还需要一位测试工程师，全职兼职均可，不知道园子里有没有高手愿意加入？要求如下：&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2009/01/13/1374557.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1374557.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47998/" target="_blank">传诺基亚正在开发Android手机</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>不得不为LINQ说几句话，驳“LINQ已死”论</title><link>http://www.cnblogs.com/Terrylee/archive/2009/01/05/LINQ-and-LINQ-to-SQL.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Sun, 04 Jan 2009 17:31:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2009/01/05/LINQ-and-LINQ-to-SQL.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1368628.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2009/01/05/LINQ-and-LINQ-to-SQL.html#Feedback</comments><slash:comments>295</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1368628.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1368628.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_vs.png" alt=""/></div>近日不断看到有关“LINQ已死”，“LINQ玩完了吧”的言论，甚至于更有牛人说出“程序开发最终会回到本机代码上”，于是便有了本文：<br/>
1.请认清事实真相<br/>
2.请区分清概念<br/>
3.请收起LINQ无用论&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2009/01/05/LINQ-and-LINQ-to-SQL.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1368628.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47996/" target="_blank">7月编程语言排行榜</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>代友招聘：ASP.NET开发人员</title><link>http://www.cnblogs.com/Terrylee/archive/2008/12/30/1365314.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Tue, 30 Dec 2008 07:21:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/12/30/1365314.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1365314.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/12/30/1365314.html#Feedback</comments><slash:comments>57</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1365314.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1365314.html</trackback:ping><description><![CDATA[<p>最近有朋友接到一个项目，是为杂志社开发一套内部办公系统，09年3月底交活，准备用ASP.NET MVC + WF开发，想从咱们园子里找2-3名高手加盟开发，待遇每人月应不会低于8,000元，要求如下：   <br />1. 09年2、3月份有充足的时间参与开发，最好这两个月能专职于本项目；    <br />2. 对待分配给自己的工作认真负责；    <br />3. 有2年以上ASP.NET开发经验，熟悉ASP.NET3.5+SP1的新特性；    <br />4. 已熟练掌握ASP.NET MVC的开发；    <br />5. 熟悉LINQ，以及ADO.NET Entity Framework；    <br />6. 最好具有WF的开发经验；    <br />7. 09年2、3月份人在北京；    <br />8. 有时需要加班工作。</p>  <p>   <br />有意者请将简历发至<strong>lovenets@sina.com</strong>或者<strong>lovenets@hotmail.com</strong></p><img src ="http://www.cnblogs.com/Terrylee/aggbug/1365314.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47995/" target="_blank">Google Voice 上手</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>[推荐]2008年第四季度开发者Top 100 Blogs</title><link>http://www.cnblogs.com/Terrylee/archive/2008/12/22/top-100-blogs-for-developers-q4-2008.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Mon, 22 Dec 2008 11:15:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/12/22/top-100-blogs-for-developers-q4-2008.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1360040.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/12/22/top-100-blogs-for-developers-q4-2008.html#Feedback</comments><slash:comments>39</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1360040.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1360040.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_blogger.png" alt=""/></div>在10月份Anytao同学推荐了Jurgen Appelo整理的Top 100 Blogs 第三季度版本，现在Jurgen Appelo又整理出了第四季度的Top 100 Blogs，其中有些Blogger的排名发生了变化，退出了前100名，而又很多新的Blogger当选，再次推荐给大家。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/12/22/top-100-blogs-for-developers-q4-2008.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1360040.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47994/" target="_blank">Google号召社区力量为互联网加速</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>应用程序架构指导袖珍版</title><link>http://www.cnblogs.com/Terrylee/archive/2008/12/08/Application-Architecture-Pocket-Guides.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Sun, 07 Dec 2008 16:33:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/12/08/Application-Architecture-Pocket-Guides.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1349845.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/12/08/Application-Architecture-Pocket-Guides.html#Feedback</comments><slash:comments>34</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1349845.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1349845.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_pandp.png" alt=""/></div>微软模式与实践小组最近发布了应用程序架构指导袖珍版本，总共有6本，分别介绍了不同类型应用程序的架构指导，包括敏捷架构方法、Mobile应用程序、RIA应用程序、富客户端应用程序、Web应用程序以及Service架构等，非常值得一看。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/12/08/Application-Architecture-Pocket-Guides.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1349845.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47989/" target="_blank">Twitter无处不在 魔兽世界Twitter发送器插件发布</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>使用微软分布式缓存服务Velocity Part 3</title><link>http://www.cnblogs.com/Terrylee/archive/2008/12/07/Microsoft-Distributed-Cache-Velocity-Part3.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Sun, 07 Dec 2008 14:42:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/12/07/Microsoft-Distributed-Cache-Velocity-Part3.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1349769.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/12/07/Microsoft-Distributed-Cache-Velocity-Part3.html#Feedback</comments><slash:comments>29</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1349769.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1349769.html</trackback:ping><description><![CDATA[<h2>概述</h2> <p>Velocity是微软推出的分布式缓存解决方案，为开发可扩展性，可用的，高性能的应用程提供支持，可以缓存各种类型的数据，如CLR对象、XML、二进制数据等，并且支持集群模式的缓存服务器。Velocity也将集成在.NET Framework 4.0中，本文将介绍Velocity中的悲观锁定，缓存项版本、日志记录、客户端缓存以及路由表等知识。  <h2>悲观锁定</h2> <p>在Velocity提供了一套悲观锁定模型，即在某个缓存项数据处理过程中，数据将处于锁定状态，来自于其它客户端应用程序将无法对该缓存项进行处理。提供悲观锁定的方法主要三个，如下代码所示：  <p><b>GetAndLock()</b>：获取缓存项并对数据加锁；  <p><b>PutAndUnlock()</b>：更新加锁的数据并释放锁；  <p><b>Unlock()</b>：释放锁定。  <p>先来看GetAndLock()方法，在获取缓存项时并加锁，此时如果其它客户端试图获取该数据并加锁（即调用GetAndLock方法）将会失败，而不会阻塞；但客户端如果只想获取数据（即调用Get方法），则会返回相应数据，可以用图1形象的来表示：  <p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="247" alt="Velocity_003" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart3_13D31/Velocity_003_3.png" width="570" border="0">  <p>图 1  <p>可以看到，ClientA获取数据成功并加锁；ClientB再次想获取数据并加锁时，将会失败；ClientC能够获取数据。  <p>使用GetAndLock()方式可以指定锁过期时间，并且会有输出参数LockHandle，该参数将会在PutAndUnlock()方法或Unlock()中来释放锁，如下代码所示：<pre class="code"><span style="color: #2b91af">Cache </span>cache = GetCurrentCache();
<span style="color: #2b91af">LockHandle </span>handle = <span style="color: blue">new </span><span style="color: #2b91af">LockHandle</span>();
<span style="color: #2b91af">Customer </span>item = (<span style="color: #2b91af">Customer</span>)cache.GetAndLock(<span style="color: #a31515">"C20081117005"</span>,
         <span style="color: blue">new </span><span style="color: #2b91af">TimeSpan</span>(0, 30, 0), <span style="color: blue">out </span>handle);

<span style="color: #2b91af">Customer </span>customer = <span style="color: blue">new </span><span style="color: #2b91af">Customer</span>()
{
    ID = <span style="color: #a31515">"C20081117005"</span>,
    FirstName = <span style="color: #a31515">"Terry"</span>,
    LastName = <span style="color: #a31515">"Lee"</span>,
    Age = 25,
    Email = <span style="color: #a31515">"lhj_cauc[#AT#]163.com"
</span>};
cache.PutAndUnlock(customer.ID, customer, handle, <span style="color: blue">null</span>);</pre><a href="http://11011.net/software/vspaste"></a>
<h2>日志记录</h2>
<p>Velocity中同样提供了日志记录的功能，我们可以在应用程序配置文件中进行设置，它支持基于控制台、基于文件以及Windows事件跟踪三种方式的记录，在配置文件中首先添加配置区：<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">section </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">fabric</span>" <span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">System.Data.Fabric.Common.ConfigFile, FabricCommon</span>"
         <span style="color: red">allowLocation</span><span style="color: blue">=</span>"<span style="color: blue">true</span>" <span style="color: red">allowDefinition</span><span style="color: blue">=</span>"<span style="color: blue">Everywhere</span>"<span style="color: blue">/&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<p>然后可以进行配置，如设置日志记录级别等：<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">fabric</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">section </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">logging</span>" <span style="color: red">path</span><span style="color: blue">=</span>""<span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">collection </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">sinks</span>" <span style="color: red">collectionType</span><span style="color: blue">=</span>"<span style="color: blue">list</span>"<span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">customType </span><span style="color: red">className</span><span style="color: blue">=</span>"<span style="color: blue">System.Data.Fabric.Common.EventLogger,FabricCommon</span>"
                  <span style="color: red">sinkName</span><span style="color: blue">=</span>"<span style="color: blue">System.Data.Fabric.Common.ConsoleSink,FabricCommon</span>"
                  <span style="color: red">sinkParam</span><span style="color: blue">=</span>"" <span style="color: red">defaultLevel</span><span style="color: blue">=</span>"<span style="color: blue">-1</span>"<span style="color: blue">/&gt;
      &lt;</span><span style="color: #a31515">customType </span><span style="color: red">className</span><span style="color: blue">=</span>"<span style="color: blue">System.Data.Fabric.Common.EventLogger,FabricCommon</span>"
                  <span style="color: red">sinkName</span><span style="color: blue">=</span>"<span style="color: blue">System.Data.Fabric.Common.FileEventSink,FabricCommon</span>"
                  <span style="color: red">sinkParam</span><span style="color: blue">=</span>"<span style="color: blue">CacheClientLog</span>" <span style="color: red">defaultLevel</span><span style="color: blue">=</span>"<span style="color: blue">1</span>"<span style="color: blue">/&gt;
      &lt;</span><span style="color: #a31515">customType </span><span style="color: red">className</span><span style="color: blue">=</span>"<span style="color: blue">System.Data.Fabric.Common.EventLogger,FabricCommon</span>"
                  <span style="color: red">sinkName</span><span style="color: blue">=</span>"<span style="color: blue">System.Data.Caching.ETWSink, CacheBaseLibrary</span>"
                  <span style="color: red">sinkParam</span><span style="color: blue">=</span>"" <span style="color: red">defaultLevel</span><span style="color: blue">=</span>"<span style="color: blue">-1</span>" <span style="color: blue">/&gt;
    &lt;/</span><span style="color: #a31515">collection</span><span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">section</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">fabric</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<p>同样也可以在代码中设置，调用CacheFactory的两个静态方法CreateLogSinks和DisableLogSinks，如下代码所示：<pre class="code"><span style="color: blue">private </span><span style="color: #2b91af">Cache </span>GetCurrentCache()
{
    <span style="color: #2b91af">List</span>&lt;<span style="color: #2b91af">LogSink</span>&gt; sinklist = <span style="color: blue">new </span><span style="color: #2b91af">List</span>&lt;<span style="color: #2b91af">LogSink</span>&gt;(2);
    <span style="color: #2b91af">LogSink </span>fileBasedSink = <span style="color: blue">new </span><span style="color: #2b91af">LogSink</span>(<span style="color: #2b91af">SinkType</span>.FILE,
        <span style="color: #2b91af">TraceLevel</span>.Warning, <span style="color: #a31515">"DCache/dd-hh-mm"</span>);
    <span style="color: #2b91af">LogSink </span>consoleBasedSink = <span style="color: blue">new </span><span style="color: #2b91af">LogSink</span>(<span style="color: #2b91af">SinkType</span>.CONSOLE,
        <span style="color: #2b91af">TraceLevel</span>.Warning);
    sinklist.Add(fileBasedSink);
    sinklist.Add(consoleBasedSink);
    <span style="color: green">// 启用
    </span><span style="color: #2b91af">CacheFactory</span>.CreateLogSinks(sinklist);

    <span style="color: green">// 禁用
    </span><span style="color: #2b91af">CacheFactory</span>.DisableLogSinks();

    <span style="color: #2b91af">Cache </span>dCache;
    <span style="color: #2b91af">ServerEndPoint</span>[] servers = <span style="color: blue">new </span><span style="color: #2b91af">ServerEndPoint</span>[1];
    servers[0] = <span style="color: blue">new </span><span style="color: #2b91af">ServerEndPoint</span>(<span style="color: #a31515">"localhost"</span>, 22233, <span style="color: #a31515">"DistributedCacheService"</span>);
    <span style="color: blue">bool </span>routingClient = <span style="color: blue">true</span>;
    <span style="color: blue">bool </span>localCache = <span style="color: blue">false</span>;

    <span style="color: blue">var </span>factory = <span style="color: blue">new </span><span style="color: #2b91af">CacheFactory</span>(servers, routingClient, localCache);
    dCache = factory.GetCache(<span style="color: #a31515">"default"</span>);

    <span style="color: blue">return </span>dCache;
}</pre><a href="http://11011.net/software/vspaste"></a>
<h2>缓存项版本</h2>
<p>在Velocity中提供了一种基于版本的更新功能，当使用GetCacheItem()方法时将返回一个缓存项，并携带有版本信息，当每次对缓存项做更新时，在内部都会对它的版本增加。如下面的示例，有两个客户应用程序，它们同时获取了同一个缓存项： 
<p><strong>ClientA</strong><pre class="code"><span style="color: #2b91af">CacheItem </span>item = cache.GetCacheItem(<span style="color: #a31515">"Customers"</span>, <span style="color: #a31515">"C2008"</span>);</pre><a href="http://11011.net/software/vspaste"></a>
<p><strong>ClientB</strong><pre class="code"><span style="color: #2b91af">CacheItem </span>item = cache.GetCacheItem(<span style="color: #a31515">"Customers"</span>, <span style="color: #a31515">"C2008"</span>);</pre><a href="http://11011.net/software/vspaste"></a>
<p>并且同时对缓存项做修改： 
<p><strong>ClientA</strong><pre class="code">((<span style="color: #2b91af">Customer</span>)item.CacheObject).FirstName = <span style="color: #a31515">"Huijun"</span>;</pre><a href="http://11011.net/software/vspaste"></a>
<p><strong>ClientB</strong><pre class="code">((<span style="color: #2b91af">Customer</span>)item.CacheObject).FirstName = <span style="color: #a31515">"Terry"</span>;</pre><a href="http://11011.net/software/vspaste"></a>
<p>如果ClientA首先提交更改，在提交更改时携带版本信息，由于版本信息与内部的版本一致，所以提交成功： 
<p><strong>ClientA</strong><pre class="code">cache.Put(<span style="color: #a31515">"Customers"</span>, <span style="color: #a31515">"C2008"</span>, item.CacheObject, item.Version);</pre><a href="http://11011.net/software/vspaste"></a>
<p>此时内部版本将会增加，现在ClientB如果再提交更改，将会失败，因为版本无法匹配，如图2表示： 
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="456" alt="Velocity_004" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart3_13D31/Velocity_004_3.png" width="509" border="0"> 
<p>图 2 
<h2>客户端缓存</h2>
<p>在Velocity中还支持客户端缓存，如果启用了客户端缓存后，在从缓存集群中取回数据时，将会放在客户端缓存中，这样下次取数据时将会直接从客户端缓存中取出，能够极大的提高效率，有点像是缓存的缓存。当集群中的数据发生变化时，Velocity将会使用事件通知机制通知客户端缓存刷新数据，如图3所示： 
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="344" alt="Velocity_005" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart3_13D31/Velocity_005_3.png" width="577" border="0"> 
<p>图 3 
<p>要启用客户端缓存，一是使用配置文件，设置IsEnabled属性为True，如下代码所示：<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">dcacheClient </span><span style="color: red">deployment</span><span style="color: blue">=</span>"<span style="color: blue">routing</span>"<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">localCache </span><strong><span style="color: red">isEnabled</span><span style="color: blue">=</span>"<span style="color: blue">true</span>"</strong> <span style="color: red">sync</span><span style="color: blue">=</span>"<span style="color: blue">TTLBased</span>" <span style="color: red">ttlValue</span><span style="color: blue">=</span>"<span style="color: blue">300</span>" <span style="color: blue">/&gt;
  &lt;</span><span style="color: #a31515">hosts</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">host </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">localhost</span>" <span style="color: red">cachePort</span><span style="color: blue">=</span>"<span style="color: blue">22233</span>" 
          <span style="color: red">cacheHostName</span><span style="color: blue">=</span>"<span style="color: blue">DistributedCacheService</span>"<span style="color: blue">/&gt;
  &lt;/</span><span style="color: #a31515">hosts</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">dcacheClient</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<p>直接指定启用客户端缓存即可，另外也可以在创建CacheFactory时指定，如下代码所示：<pre class="code"><span style="color: #2b91af">Cache </span>dCache;
<span style="color: #2b91af">ServerEndPoint</span>[] servers = <span style="color: blue">new </span><span style="color: #2b91af">ServerEndPoint</span>[1];
servers[0] = <span style="color: blue">new </span><span style="color: #2b91af">ServerEndPoint</span>(<span style="color: #a31515">"localhost"</span>, 22233, <span style="color: #a31515">"DistributedCacheService"</span>);
<span style="color: blue">bool </span>routingClient = <span style="color: blue">true</span>;
<strong><span style="color: blue">bool </span>localCache = <span style="color: blue">false</span>;</strong>

<span style="color: blue">var </span>factory = <span style="color: blue">new </span><span style="color: #2b91af">CacheFactory</span>(servers, routingClient, localCache);
dCache = factory.GetCache(<span style="color: #a31515">"default"</span>);

<span style="color: blue">return </span>dCache;</pre><a href="http://11011.net/software/vspaste"></a>
<h2>路由客户端</h2>
<p>Velocity中在缓存客户端，提供了一种路由客户端Routing Client，它能够提供比简单客户端Simple Client更好的性能，在Routing Client中会有一个路由表Routing Table，它用来跟踪缓存对象，它是全局缓存中的分区映射的一个子集，同时分发缓存操作（Put、Get等）到确定的缓存宿主。路由客户端使用此路由表来优化性能，因为该表可以跟踪缓存对象，所以当有请求到缓存宿主时，可以进行物理上的定位。如图4所示： 
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="367" alt="Velocity_007" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart3_13D31/Velocity_007_3.png" width="580" border="0"> 
<p>图4 
<p>是否在应用程序中启用路由客户端，可以由开发者来确定，如在配置中启用路由客户端，这里可以通过指示deployment来设定是路由客户端（routing）还是简单客户端（simple）：<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">dcacheClient </span><span style="color: red">deployment</span><span style="color: blue">=</span>"<span style="color: blue">routing</span>"<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">localCache </span><span style="color: red">isEnabled</span><span style="color: blue">=</span>"<span style="color: blue">true</span>" <span style="color: red">sync</span><span style="color: blue">=</span>"<span style="color: blue">TTLBased</span>" <span style="color: red">ttlValue</span><span style="color: blue">=</span>"<span style="color: blue">300</span>" <span style="color: blue">/&gt;
  &lt;</span><span style="color: #a31515">hosts</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">host </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">localhost</span>" <span style="color: red">cachePort</span><span style="color: blue">=</span>"<span style="color: blue">22233</span>" 
          <span style="color: red">cacheHostName</span><span style="color: blue">=</span>"<span style="color: blue">DistributedCacheService</span>"<span style="color: blue">/&gt;
  &lt;/</span><span style="color: #a31515">hosts</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">dcacheClient</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<p>另外还可以通过代码来设置，如下面的代码，在创建CacheFactory时指定构造函数参数：<pre class="code"><span style="color: #2b91af">Cache </span>dCache;
<span style="color: #2b91af">ServerEndPoint</span>[] servers = <span style="color: blue">new </span><span style="color: #2b91af">ServerEndPoint</span>[1];
servers[0] = <span style="color: blue">new </span><span style="color: #2b91af">ServerEndPoint</span>(<span style="color: #a31515">"localhost"</span>, 22233, <span style="color: #a31515">"DistributedCacheService"</span>);
<span style="color: blue">bool </span>routingClient = <span style="color: blue">true</span>;
<span style="color: blue">bool </span>localCache = <span style="color: blue">false</span>;

<span style="color: blue">var </span>factory = <span style="color: blue">new </span><span style="color: #2b91af">CacheFactory</span>(servers, routingClient, localCache);
dCache = factory.GetCache(<span style="color: #a31515">"default"</span>);

<span style="color: blue">return </span>dCache;</pre><a href="http://11011.net/software/vspaste"></a>
<h2>Velocity组成</h2>
<p>最后我们再看一幅图，来了解一下Velocity的组成部分，可以看到它可以分为客户端缓存、服务端缓存以及管理工具三部分，如图5所示： 
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="423" alt="Velocity_006" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart3_13D31/Velocity_006_3.png" width="580" border="0"> 
<p>图 5 
<h2>总结</h2>
<p>本文介绍了Velocity中的悲观锁定，缓存项版本、日志记录、客户端缓存以及路由表等知识，希望对大家有用。至此，关于微软的分布式缓存服务Velocity就用短短的三篇文章介绍到这里，期待在.NET Framework 4.0中Velocity能够为我们带来更多的惊喜。 
<p>相关文章： 
<p>1. <a href="http://www.cnblogs.com/Terrylee/archive/2008/11/20/Microsoft-Distributed-Cache-Velocity-Part1.html">使用微软分布式缓存服务Velocity Part 1</a> 
<p>2. <a href="http://www.cnblogs.com/Terrylee/archive/2008/11/21/Microsoft-Distributed-Cache-Velocity-Part2.html">使用微软分布式缓存服务Velocity Part 2</a></p><img src ="http://www.cnblogs.com/Terrylee/aggbug/1349769.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47988/" target="_blank">Firefox 3.5匆忙推出漏洞多 Mozilla本月将更新</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>写在WinHEC开幕之际：沿着Windows我们一路走来</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/23/1339477.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Sun, 23 Nov 2008 10:59:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/23/1339477.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1339477.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/23/1339477.html#Feedback</comments><slash:comments>33</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1339477.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1339477.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_winHEC.png" alt=""/></div>微软 2008 Windows 硬件工程大会（Windows Hardware Engineering Conference 2008，简称WinHEC 2008 China）即将于 2008年12月3-4日在北京万豪酒店盛大开幕，今年是微软第一次在中国独立举办WinHEC大会，以至于JesseQu用WinHEC终于来了一文回忆了自己近18年软件开发工作中对驱动、内核层次开发工作的情愫感慨。在WinHEC 2008开幕之际，让我们一起来回顾一下Windows的发展历史，寻找那些曾经熟悉的符号。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/11/23/1339477.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1339477.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47987/" target="_blank">预测：Twitter最可能收购的十家公司</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>使用微软分布式缓存服务Velocity Part 2</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/21/Microsoft-Distributed-Cache-Velocity-Part2.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Thu, 20 Nov 2008 16:00:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/21/Microsoft-Distributed-Cache-Velocity-Part2.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1338062.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/21/Microsoft-Distributed-Cache-Velocity-Part2.html#Feedback</comments><slash:comments>54</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1338062.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1338062.html</trackback:ping><description><![CDATA[<h2>概述</h2> <p>Velocity是微软推出的分布式缓存解决方案，为开发可扩展性，可用的，高性能的应用程提供支持，可以缓存各种类型的数据，如CLR对象、XML、二进制数据等，并且支持集群模式的缓存服务器。Velocity也将集成在.NET Framework 4.0中，本文将介绍Velocity中的配置模型、缓存复杂数据和创建分区、使用标签以及ASP.NET SessionState提供者。  <h2>配置模型</h2> <p>在本文开始之前，先简单介绍一下Velocity中的配置模型，主要包括三方面的配置，缓存集群的配置，缓存宿主服务器配置以及应用程序的配置，如下图所示：  <p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="309" alt="Velocity_001" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart2_14B47/Velocity_001_3.png" width="580" border="0">  <p>缓存集群的配置，可以基于XML、SQL Server CE或者SQL Server数据库来进行存储，包括各个服务器以及所有的命名缓存、是否过期等配置，当我们使用Windows PowerShell管理工具进行配置时，将会修改该配置文件，如下代码所示：<pre class="code"><span style="color: blue">&lt;?</span><span style="color: #a31515">xml </span><span style="color: red">version</span><span style="color: blue">=</span>"<span style="color: blue">1.0</span>" <span style="color: red">encoding</span><span style="color: blue">=</span>"<span style="color: blue">utf-8</span>"<span style="color: blue">?&gt;
&lt;</span><span style="color: #a31515">configuration</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">configSections</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">section </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">dcache</span>" <span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">System.Data.Caching.DCacheSection, 
             CacheBaseLibrary, Version=1.0.0.0, Culture=neutral,
             PublicKeyToken=89845dcd8080cc91</span>" <span style="color: blue">/&gt;
  &lt;/</span><span style="color: #a31515">configSections</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">dcache </span><span style="color: red">cluster</span><span style="color: blue">=</span>"<span style="color: blue">localhost</span>" <span style="color: red">size</span><span style="color: blue">=</span>"<span style="color: blue">Small</span>"<span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">caches</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">cache </span><span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">partitioned</span>" <span style="color: red">consistency</span><span style="color: blue">=</span>"<span style="color: blue">strong</span>" <span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">default</span>"<span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">policy</span><span style="color: blue">&gt;
          &lt;</span><span style="color: #a31515">eviction </span><span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">lru</span>" <span style="color: blue">/&gt;
          &lt;</span><span style="color: #a31515">expiration </span><span style="color: red">defaultTTL</span><span style="color: blue">=</span>"<span style="color: blue">10</span>" <span style="color: red">isExpirable</span><span style="color: blue">=</span>"<span style="color: blue">true</span>" <span style="color: blue">/&gt;
        &lt;/</span><span style="color: #a31515">policy</span><span style="color: blue">&gt;
      &lt;/</span><span style="color: #a31515">cache</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">cache </span><span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">partitioned</span>" <span style="color: red">consistency</span><span style="color: blue">=</span>"<span style="color: blue">strong</span>" <span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">other</span>"<span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">policy</span><span style="color: blue">&gt;
          &lt;</span><span style="color: #a31515">eviction </span><span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">lru</span>" <span style="color: blue">/&gt;
          &lt;</span><span style="color: #a31515">expiration </span><span style="color: red">defaultTTL</span><span style="color: blue">=</span>"<span style="color: blue">10</span>" <span style="color: red">isExpirable</span><span style="color: blue">=</span>"<span style="color: blue">true</span>" <span style="color: blue">/&gt;
        &lt;/</span><span style="color: #a31515">policy</span><span style="color: blue">&gt;
      &lt;/</span><span style="color: #a31515">cache</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">caches</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">hosts</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">host </span><span style="color: red">clusterPort</span><span style="color: blue">=</span>"<span style="color: blue">22234</span>" <span style="color: red">hostId</span><span style="color: blue">=</span>"<span style="color: blue">1319514812</span>" <span style="color: red">size</span><span style="color: blue">=</span>"<span style="color: blue">1024</span>" <span style="color: red">quorumHost</span><span style="color: blue">=</span>"<span style="color: blue">true</span>"
          <span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">TERRYLEE-PC</span>" <span style="color: red">cacheHostName</span><span style="color: blue">=</span>"<span style="color: blue">DistributedCacheService</span>"
          <span style="color: red">cachePort</span><span style="color: blue">=</span>"<span style="color: blue">22233</span>" <span style="color: blue">/&gt;
    &lt;/</span><span style="color: #a31515">hosts</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">advancedProperties</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">partitionStoreConnectionSettings </span><span style="color: red">providerName</span><span style="color: blue">=</span>"<span style="color: blue">System.Data.SqlServerCe.3.5</span>"
          <span style="color: red">connectionString</span><span style="color: blue">=</span>"<span style="color: blue">D:\CacheShare\ConfigStore.sdf</span>" <span style="color: blue">/&gt;
    &lt;/</span><span style="color: #a31515">advancedProperties</span><span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">dcache</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">configuration</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a>
<p>在上一篇的示例中，并没有使用应用程序配置文件，事实上使用配置文件是更好的编程实践，首先需要添加一个配置区：<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">section </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">dcacheClient</span>"
<span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">System.Data.Caching.DCacheSection, 
      CacheBaseLibrary, Version=1.0.0.0, 
      Culture=neutral, PublicKeyToken=89845dcd8080cc91</span>"<span style="color: blue">/&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<p>配置信息包括部署方式，是否启用本地缓存以及缓存宿主等，如下代码所示：<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">dcacheClient</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">localCache </span><span style="color: red">isEnabled</span><span style="color: blue">=</span>"<span style="color: blue">true</span>" <span style="color: red">sync</span><span style="color: blue">=</span>"<span style="color: blue">TTLBased</span>" <span style="color: red">ttlValue</span><span style="color: blue">=</span>"<span style="color: blue">300</span>" <span style="color: blue">/&gt;
  &lt;</span><span style="color: #a31515">hosts</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">host </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">localhost</span>" <span style="color: red">cachePort</span><span style="color: blue">=</span>"<span style="color: blue">22233</span>" 
          <span style="color: red">cacheHostName</span><span style="color: blue">=</span>"<span style="color: blue">DistributedCacheService</span>"<span style="color: blue">/&gt;
  &lt;/</span><span style="color: #a31515">hosts</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">dcacheClient</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a>
<p>现在Velocity CTP2对于应用程序使用配置的支持似乎有些问题。缓存宿主的配置放在DistributedCache.exe.config文件中，可以在Velocity安装目录下找到。 
<h2>缓存复杂数据类型</h2>
<p>在Velocity中，可以缓存任何类型的数据，如CLR对象、XML或者二进制数据等。现在看一个简单的示例，如何缓存复杂类型数据，定义一个如下的Customer类，注意要能够序列化：<pre class="code">[<span style="color: #2b91af">Serializable</span>]
<span style="color: blue">public class </span><span style="color: #2b91af">Customer
</span>{
    <span style="color: blue">public </span><span style="color: #2b91af">String </span>ID { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }

    <span style="color: blue">public </span><span style="color: #2b91af">String </span>FirstName { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }

    <span style="color: blue">public </span><span style="color: #2b91af">String </span>LastName { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }

    <span style="color: blue">public int </span>Age { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }

    <span style="color: blue">public </span><span style="color: #2b91af">String </span>Email { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }
}</pre><a href="http://11011.net/software/vspaste"></a>
<p>对应用程序做配置，参考本文的配置模型部分，使用方法与简单数据类型的基本一致，如添加缓存项，使用Customer主键作为缓存键，其中GetCurrentCache()方法的实现请参考上一篇文章：<pre class="code"><span style="color: #2b91af">Cache </span>cache = GetCurrentCache();
<span style="color: #2b91af">Customer </span>customer = <span style="color: blue">new </span><span style="color: #2b91af">Customer</span>()
{
    ID = <span style="color: #a31515">"C20081117002"</span>,
    FirstName = <span style="color: #a31515">"Terry"</span>,
    LastName = <span style="color: #a31515">"Lee"</span>,
    Age = 25,
    Email = <span style="color: #a31515">"lhj_cauc[#AT#]163.com"
</span>};

cache.Add(customer.ID, customer);</pre><a href="http://11011.net/software/vspaste"></a>
<p>获取缓存项：<pre class="code"><span style="color: #2b91af">Cache </span>cache = GetCurrentCache();
<span style="color: #2b91af">Customer </span>customer = cache.Get(<span style="color: #a31515">"C20081117002"</span>) <span style="color: blue">as </span><span style="color: #2b91af">Customer</span>;</pre><a href="http://11011.net/software/vspaste"></a>
<p>移除缓存项：<pre class="code"><span style="color: #2b91af">Cache </span>cache = GetCurrentCache();
cache.Remove(<span style="color: #a31515">"C20081117002"</span>);</pre><a href="http://11011.net/software/vspaste"></a>
<p>更新缓存中数据，可以有两种方法，一是直接使用缓存索引，如果确保缓存键存在：<pre class="code"><span style="color: #2b91af">Cache </span>cache = GetCurrentCache();
<span style="color: #2b91af">Customer </span>customer = <span style="color: blue">new </span><span style="color: #2b91af">Customer</span>()
{
    ID = <span style="color: #a31515">"C20081117002"</span>,
    FirstName = <span style="color: #a31515">"Huijui"</span>,
    LastName = <span style="color: #a31515">"Li"</span>,
    Age = 26,
    Email = <span style="color: #a31515">"lhj_cauc[#AT#]163.com"
</span>};
cache[<span style="color: #a31515">"C20081117002"</span>] = customer;</pre><a href="http://11011.net/software/vspaste"></a>
<p>另外一种是使用Put方法，如果缓存键不存在，它将会新增到缓存中，否则会进行覆盖，如下代码所示：<pre class="code"><span style="color: #2b91af">Cache </span>cache = GetCurrentCache();
<span style="color: #2b91af">Customer </span>customer = <span style="color: blue">new </span><span style="color: #2b91af">Customer</span>()
{
    ID = <span style="color: #a31515">"C20081117002"</span>,
    FirstName = <span style="color: #a31515">"Huijui"</span>,
    LastName = <span style="color: #a31515">"Li"</span>,
    Age = 26,
    Email = <span style="color: #a31515">"lhj_cauc[#AT#]163.com"
</span>};
cache.Put(customer.ID, customer);</pre><a href="http://11011.net/software/vspaste"></a>
<h2>使用分区</h2>
<p>在实际部署中，经常会出现多个应用程序共享同一个缓存集群，这不可避免的会出现缓存键冲突，如上面的示例中使用CustomerID作为缓存键，此时可以使用Velocity中的分区功能，它会在逻辑上把各个命名缓存再进行分区，这样可以完全保持数据隔离，如下图所示： 
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="387" alt="TerryLee_0216" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart2_14B47/TerryLee_0216_3.png" width="519" border="0"> 
<p>图中共有三个命名缓存，其中在缓存Catalog中又分区为Sports和Arts。在Velocity中对于分区的操作提供了如下三个方法，可以用于创建分区，删除分区以及清空分区中所有的对象：<pre class="code"><span style="color: blue">public void </span>ClearRegion(<span style="color: blue">string </span>region);
<span style="color: blue">public bool </span>CreateRegion(<span style="color: blue">string </span>region, <span style="color: blue">bool </span>evictable);
<span style="color: blue">public bool </span>RemoveRegion(<span style="color: blue">string </span>region);</pre><a href="http://11011.net/software/vspaste"></a>
<p>如下代码所示，创建了一个名为“Customers”的分区，在调用Add方法时可以指定数据将会缓存到哪个分区：<pre class="code"><span style="color: #2b91af">Cache </span>cache = GetCurrentCache();
<span style="color: blue">string </span>regionName = <span style="color: #a31515">"Customers"</span>;
cache.CreateRegion(regionName, <span style="color: blue">false</span>);

<span style="color: #2b91af">Customer </span>customer = <span style="color: blue">new </span><span style="color: #2b91af">Customer</span>()
{
    ID = <span style="color: #a31515">"C20081117003"</span>,
    FirstName = <span style="color: #a31515">"Terry"</span>,
    LastName = <span style="color: #a31515">"Lee"</span>,
    Age = 25,
    Email = <span style="color: #a31515">"lhj_cauc[#AT#]163.com"
</span>};

cache.Add(regionName, customer.ID, customer);</pre><a href="http://11011.net/software/vspaste"></a>
<p>可以使用Get-CacheRegion命令在Windows PowerShell中来查看一下当前缓存集群中所有的分区信息，如下图所示： 
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="222" alt="Velocity_002" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart2_14B47/Velocity_002_3.png" width="580" border="0"> 
<p>同样在检索缓存数据时，仍然可以使用分区名进行检索。 
<h2>使用标签</h2>
<p>在Velocity还允许对加入到缓存中的缓存项设置Tag，可以是一个或者多个，使用了Tag，就可以从多个方面对缓存项进行描述，这样在检索数据时，就可以根据Tag来一次检索多个缓存项。为缓存项设置Tag，如下代码所示：<pre class="code"><span style="color: #2b91af">Cache </span>cache = GetCurrentCache();
<span style="color: blue">string </span>regionName = <span style="color: #a31515">"Customers"</span>;

<span style="color: #2b91af">Customer </span>customer1 = <span style="color: blue">new </span><span style="color: #2b91af">Customer</span>()
{
    ID = <span style="color: #a31515">"C20081117004"</span>,
    FirstName = <span style="color: #a31515">"Terry"</span>,
    LastName = <span style="color: #a31515">"Lee"</span>,
    Age = 25,
    Email = <span style="color: #a31515">"lhj_cauc[#AT#]163.com"
</span>};
<span style="color: #2b91af">Customer </span>customer2 = <span style="color: blue">new </span><span style="color: #2b91af">Customer</span>()
{
    ID = <span style="color: #a31515">"C20081117005"</span>,
    FirstName = <span style="color: #a31515">"Terry"</span>,
    LastName = <span style="color: #a31515">"Lee"</span>,
    Age = 25,
    Email = <span style="color: #a31515">"lhj_cauc[#AT#]163.com"
</span>};

<span style="color: #2b91af">Tag </span>tag1 = <span style="color: blue">new </span><span style="color: #2b91af">Tag</span>(<span style="color: #a31515">"Beijing"</span>);
<span style="color: #2b91af">Tag </span>tag2 = <span style="color: blue">new </span><span style="color: #2b91af">Tag</span>(<span style="color: #a31515">"Tianjin"</span>);
cache.Add(regionName, customer1.ID, customer1, <span style="color: blue">new </span><span style="color: #2b91af">Tag</span>[] { tag1, tag2 });
cache.Add(regionName, customer2.ID, customer2, <span style="color: blue">new </span><span style="color: #2b91af">Tag</span>[] { tag2 });</pre><a href="http://11011.net/software/vspaste"></a>
<p>这样就可以对设置了Tag的缓存项进行检索，根据实际需求选择使用如下三个方法之一：<pre class="code">GetAllMatchingTags(<span style="color: blue">string </span>region, <span style="color: #2b91af">Tag</span>[] tags)
GetAnyMatchingTag(<span style="color: blue">string </span>region, <span style="color: #2b91af">Tag</span>[] tags)
GetByTag(<span style="color: blue">string </span>region, <span style="color: #2b91af">Tag </span>tag)</pre><a href="http://11011.net/software/vspaste"></a>
<p>第一个检索匹配所有Tag的数据，第二个检索匹配所有Tag中的任意一个即可，最后只使用一个Tag，如下代码所示：<pre class="code"><span style="color: blue">string </span>regionName = <span style="color: #a31515">"Customers"</span>;
<span style="color: #2b91af">Tag</span>[] tags = <span style="color: blue">new </span><span style="color: #2b91af">Tag</span>[] { <span style="color: blue">new </span><span style="color: #2b91af">Tag</span>(<span style="color: #a31515">"Beijing"</span>), 
           <span style="color: blue">new </span><span style="color: #2b91af">Tag</span>(<span style="color: #a31515">"Tianjin"</span>)};

<span style="color: #2b91af">List</span>&lt;<span style="color: #2b91af">KeyValuePair</span>&lt;<span style="color: blue">string</span>, <span style="color: blue">object</span>&gt;&gt; result
    = cache.GetAllMatchingTags(regionName, tags);</pre><a href="http://11011.net/software/vspaste"></a>
<p>使用Tag功能对于检索缓存项提供了极大的灵活性，对于任何一个数据，都可以使用多个Tag从很多方面去描述它。 
<h2>ASP.NET SessionState提供者</h2>
<p>Velocity还提供了对于ASP.NET SessionState提供者的支持，可以通过配置把Session信息缓存到缓存集群中，添加Velocity配置区：<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">section </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">dcacheClient</span>"
         <span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">System.Data.Caching.DCacheSection, 
         CacheBaseLibrary, Version=1.0.0.0, 
         Culture=neutral, PublicKeyToken=89845dcd8080cc91</span>"<span style="color: blue">/&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<p>配置缓存客户端信息：<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">dcacheClient</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">localCache </span><span style="color: red">isEnabled</span><span style="color: blue">=</span>"<span style="color: blue">true</span>" <span style="color: red">sync</span><span style="color: blue">=</span>"<span style="color: blue">TTLBased</span>" <span style="color: red">ttlValue</span><span style="color: blue">=</span>"<span style="color: blue">300</span>" <span style="color: blue">/&gt;
  &lt;</span><span style="color: #a31515">hosts</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">host </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">localhost</span>" <span style="color: red">cachePort</span><span style="color: blue">=</span>"<span style="color: blue">22233</span>" 
          <span style="color: red">cacheHostName</span><span style="color: blue">=</span>"<span style="color: blue">DistributedCacheService</span>"<span style="color: blue">/&gt;
  &lt;/</span><span style="color: #a31515">hosts</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">dcacheClient</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a>
<p>配置SessionState信息：<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">sessionState </span><span style="color: red">mode</span><span style="color: blue">=</span>"<span style="color: blue">Custom</span>" <span style="color: red">customProvider</span><span style="color: blue">=</span>"<span style="color: blue">Velocity</span>"<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">providers</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">add </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">Velocity</span>" 
         <span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">System.Data.Caching.SessionStoreProvider,ClientLibrary</span>"
         <span style="color: red">cacheName</span><span style="color: blue">=</span>"<span style="color: blue">default</span>"<span style="color: blue">/&gt;
  &lt;/</span><span style="color: #a31515">providers</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">sessionState</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<p>需要指定使用哪个命名缓存，但是该功能似乎到目前还存在问题，无法测试通过L 
<h2>总结</h2>
<p>本文简单介绍了Velocity的配置模型，以及如何缓存复杂数据类型，对命名缓存分区，为缓存项设置Tag，以及对于ASP.NET SessionState的支持，希望对大家有用。</p>
<p>相关文章：</p>
<p>1. <a href="http://www.cnblogs.com/Terrylee/archive/2008/11/20/Microsoft-Distributed-Cache-Velocity-Part1.html">使用微软分布式缓存服务Velocity Part 1</a></p><img src ="http://www.cnblogs.com/Terrylee/aggbug/1338062.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47986/" target="_blank">网易澄清:与暴雪合资公司仅提供技术支持</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>使用微软分布式缓存服务Velocity Part 1</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/20/Microsoft-Distributed-Cache-Velocity-Part1.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Wed, 19 Nov 2008 16:01:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/20/Microsoft-Distributed-Cache-Velocity-Part1.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1337121.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/20/Microsoft-Distributed-Cache-Velocity-Part1.html#Feedback</comments><slash:comments>80</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1337121.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1337121.html</trackback:ping><description><![CDATA[<h2>概述</h2> <p>Velocity是微软推出的分布式缓存解决方案，为开发可扩展性，可用的，高性能的应用程提供支持，可以缓存各种类型的数据，如CLR对象、XML、二进制数据等，并且支持集群模式的缓存服务器。Velocity也将集成在.NET Framework 4.0中，本文将介绍Velocity的一些预备知识、安装配置以及开发一个简单的示例。  <h2>简介</h2> <p>既然是分布式的缓存平台，客户端应用程序能够与缓存服务器集群中的任何一台服务器通信，并且执行缓存操作，如新增缓存项，移除缓存项等。在Velocity中，提供了一套统一的API，开发者可以使用任何一种.NET语言来访问这些API，如图1所示：  <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="384" alt="TerryLee_0212" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart1_149E6/TerryLee_0212_3.png" width="580" border="0">  <p>图 1 <h2>物理模型</h2> <p>在整个Velocity分布式缓存解决方案中，从物理模型上来看，主要涉及到如下几个元素：缓存宿主，缓存集群，Velocity提供的基于Windows PowerShell的管理工具，对于服务器集群配置的存储。缓存宿主是指一个或者多个以Windows服务形式运行的服务器，每台服务器都可以运行缓存宿主服务；缓存集群是一个或者多个缓存宿主实例的集合；当缓存集群启动时，它将从集群配置存储位置处来获取配置信息，Velocity提供了多种方式的集群配置信息存储，可以基于XML文件、SQL Server数据库或者SQL Server CE等；基于PowerShell的管理工具后面会详细讲到。 如图2所示：  <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="365" alt="TerryLee_0213" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart1_149E6/TerryLee_0213_3.png" width="564" border="0">&nbsp; <p>图 2 <h2>逻辑模型</h2> <p>从逻辑模型上来看，在Velocity中主要有命名缓存，在命名缓存中我们还可以继续分区，命名缓存，可以理解为内存中的一个独立的存储结构单元，它们之间完全互相隔离，互不干扰，当有多个应用程序共享同一个缓存集群时，可以为每个应用程序分别建立命名缓存；在同一个命名缓存中，还可以对命名缓存进行分区，这样即可以解决数据冲突的问题，再配合Velocity中的“标签”功能，可以极大的提高检索效率。如图3所示：  <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="387" alt="TerryLee_0216" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart1_149E6/TerryLee_0216_3.png" width="519" border="0">&nbsp;&nbsp; <p>图 3 <h2>安装</h2> <p>Velocity当前最新的版本是CTP 2，大家可以到微软官方站点下载，由于Velocity中提供了一套基于Windows PowerShell的管理工具，所以在安装之前需要首先安装Windows PowerShell。在安装过程中，其中有一步需要进行服务器集群的配置，如图4所示：  <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="415" alt="TerryLee_0214" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart1_149E6/TerryLee_0214_3.png" width="544" border="0">  <p>图 4 <p>需要设置服务及集群端口号，集群配置的存储位置，集群配置存储的Provider，可以基于XML存储或者基于SQL Server CE存储等。另外可以访问如下站点获得一些资源：  <p>团队博客：<a href="http://blogs.msdn.com/velocity/">http://blogs.msdn.com/velocity/</a>&nbsp; <p>示例代码：<a href="http://code.msdn.microsoft.com/velocity">http://code.msdn.microsoft.com/velocity</a>  <p>安装完成后，请在Windows Service中启动Microsoft project code named "Velocity"服务。  <h2>管理工具</h2> <p>Velocity提供了基于Windows PowerShell的管理工具，对于Windows PowerShell不熟悉的可以参考《<b><a href="http://www.cnblogs.com/Terrylee/archive/2008/11/09/Windows-PowerShell-Overview.html">回归Dos操作的快感，进入PowerShell世界</a></b>》这篇文章。使用Windows PowerShell可以非常方便的对Velocity缓存集群、缓存宿主等进行管理。使用如下命令金额图对启动、停止、重启服务器集群： <pre class="code">Start-CacheCluster 
Stop-CacheCluster 
Restart-CacheCluster </pre><a href="http://11011.net/software/vspaste"></a>
<p>使用如下命令可以启动、停止缓存宿主、获取命名缓存、获取缓存分区等： <pre class="code">Get-CacheHost 
Get-CacheConfig 
Set-CacheConfig 
Start-CacheHost 
Stop-CacheHost 
Get-CacheStatistics 
Get-Cache 
Get-CacheRegion </pre><a href="http://11011.net/software/vspaste"></a>
<p>如使用Get-CacheHost命令获取缓存宿主的信息，如图5所示，可以看到宿主对应的服务名以及服务状态等： 
<p><img height="273" alt="TerryLee_0217" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart1_149E6/TerryLee_0217_3.png" width="580" border="0"> 
<p>图 5
<p>使用Get-Cache命名查看所有的命名缓存，如图6所示： 
<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="273" alt="TerryLee_0218" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart1_149E6/TerryLee_0218_3.png" width="580" border="0"> 
<p>图 6
<p>使用该管理工具还可以创建、移除命名缓存等，这里不再叙述。 
<h2>简单示例</h2>
<p>经过前面一大堆的理论介绍，现在来看一个最简单的示例。首先要把CacheBaseLibrary和ClientLibrary这两个程序集添加到应用程中，在Velocity安装目录下可以找到，并且引入命名空间： <pre class="code"><span style="color: blue">using </span>System.Data.Caching;</pre><a href="http://11011.net/software/vspaste"></a>
<p>在使用Velocity缓存数据时，首先需要创建一个命名缓存，它可以通过CacheFactory来创建，如下代码所示： <pre class="code"><span style="color: blue">private </span><span style="color: #2b91af">Cache </span>GetCurrentCache()
{
    <span style="color: #2b91af">Cache </span>dCache;
    <span style="color: #2b91af">ServerEndPoint</span>[] servers = <span style="color: blue">new </span><span style="color: #2b91af">ServerEndPoint</span>[1];
    servers[0] = <span style="color: blue">new </span><span style="color: #2b91af">ServerEndPoint</span>(<span style="color: #a31515">"localhost"</span>, 22233, <span style="color: #a31515">"DistributedCacheService"</span>);
    <span style="color: blue">bool </span>routingClient = <span style="color: blue">true</span>;
    <span style="color: blue">bool </span>localCache = <span style="color: blue">false</span>;
    <span style="color: blue">var </span>factory = <span style="color: blue">new </span><span style="color: #2b91af">CacheFactory</span>(servers, routingClient, localCache);
    dCache = factory.GetCache(<span style="color: #a31515">"default"</span>);

    <span style="color: blue">return </span>dCache;
}</pre><a href="http://11011.net/software/vspaste"></a>
<p>此处首先指定了所有的服务器信息，当然这些都可以放在应用程序配置文件中，将会在下篇中介绍，有了Cache对象，其它的使用就非常方便了，如我们可以使用Add、Put、Remove、Get等方法来对缓存项进行操作， 
<p>添加缓存项： <pre class="code"><span style="color: #2b91af">Cache </span>dCache = GetCurrentCache();

<span style="color: #2b91af">String </span>key = keyTextbox.Text;
<span style="color: #2b91af">String </span>val = valueTxtBox.Text;

<span style="color: blue">if </span>(key == <span style="color: #a31515">"" </span>|| val == <span style="color: #a31515">""</span>) <span style="color: blue">return</span>;

dCache.Add(key, val);
statusLabel.Text =
    <span style="color: #2b91af">String</span>.Format(<span style="color: #a31515">"Successfully added key {0} to cache."</span>, key);</pre><a href="http://11011.net/software/vspaste"></a>
<p>获取缓存项： <pre class="code"><span style="color: #2b91af">Cache </span>dCache = GetCurrentCache();
<span style="color: #2b91af">String </span>key = keyTextbox.Text;

<span style="color: blue">if </span>(key == <span style="color: #a31515">""</span>) <span style="color: blue">return</span>;

<span style="color: #2b91af">String </span>val = dCache.Get(key).ToString();
valueTxtBox.Text = val;
statusLabel.Text =
    <span style="color: #2b91af">String</span>.Format(<span style="color: #a31515">"Successfully did Get of key {0} from cache"</span>, key);</pre><a href="http://11011.net/software/vspaste"></a>
<p>运行程序可以测试，数据被正确的缓存，如图7所示：
<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="334" alt="TerryLee_0219" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart1_149E6/TerryLee_0219_3.png" width="472" border="0"> 
<p>图 7
<h2>总结</h2>
<p>本文简单介绍了微软的分布式缓存解决方案Velocity的一些概念以及开发了一个简单的示例，希望对大家有用。在下篇文章中，我们将会更深入学习缓存复杂数据类型以及Velocity的编程模型和配置模型。</p>
<p>相关文章：</p>
<p>1. <a href="http://www.cnblogs.com/Terrylee/archive/2008/11/21/Microsoft-Distributed-Cache-Velocity-Part2.html">使用微软分布式缓存服务Velocity Part 2 </a></p><img src ="http://www.cnblogs.com/Terrylee/aggbug/1337121.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47985/" target="_blank">杰克逊悼念仪式或成史上最大规模Web活动</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>Silverlight 3一瞥</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/18/Silverlight-v3-Overview.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Mon, 17 Nov 2008 16:01:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/18/Silverlight-v3-Overview.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1335510.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/18/Silverlight-v3-Overview.html#Feedback</comments><slash:comments>74</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1335510.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1335510.html</trackback:ping><description><![CDATA[<p>今天<a href="http://weblogs.asp.net/scottgu/default.aspx">ScottGu</a>在自己的Blog上对目前正在开发中的Silverlight 3版本的新特性做了一些透露，Silverlight 3的新特性包括视频方面的增强，包括支持H.264 video；图形方面的增强包括3D支持和GPU硬件加速；开发方面的增强包括更加丰富的数据绑定支持和更多的控件。另外，从Silverlight 3起在开发工具方面也会有较大的改进，将会完全支持在Visual Studio或者Visual Web Developer Express中进行Silverlight应用程序的编写和交互设计（这点也是Silverlight 2在Visual Studio 2008中开发最为开发者诟病的一点），另外还会为数据绑定提供可视化工具，类似于ASP.NET中的数据绑定一样，如下图所示：</p> <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="418" alt="TerryLee_0211" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/Silverlight3_14F3D/TerryLee_0211_3.png" width="580" border="0">&nbsp;</p> <p>原文请参考：<a href="http://weblogs.asp.net/scottgu/archive/2008/11/16/update-on-silverlight-2-and-a-glimpse-of-silverlight-3.aspx">Update on Silverlight 2 - and a glimpse of Silverlight 3</a></p><img src ="http://www.cnblogs.com/Terrylee/aggbug/1335510.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47984/" target="_blank">《商业周刊》:Mozilla的志愿者开发模式被复制</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>WCF后传系列（10）：消息处理功能核心</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/17/WCF-Messaging-Features-Core.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Mon, 17 Nov 2008 15:46:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/17/WCF-Messaging-Features-Core.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1335498.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/17/WCF-Messaging-Features-Core.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1335498.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1335498.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_wcf.png" alt=""/></div>WCF是一个通信框架，同时也可以将它看成是一个消息处理或者传递的基础框架，它可以接收消息、对消息做处理，或者根据客户端给定的数据构造消息并将消息发送到目标端点，在这个过程中，一切都是围绕“消息”而展开的。WCF在消息处理体系结构提供统一编程模型的同时，还允许灵活的表示数据和传递消息，本文将介绍如何配置消息支持各个SOAP和WS-Addressing版本或者不用任何SOAP和WS-Addressing，以及如何控制消息状态等。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/11/17/WCF-Messaging-Features-Core.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1335498.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47977/" target="_blank">Mono 的Virtual PC 虚拟机</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>WCF后传系列（9）：深度通道编程模型Part 2—实例篇</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/14/WCF-Channel-Programming-Model-Example.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Thu, 13 Nov 2008 16:22:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/14/WCF-Channel-Programming-Model-Example.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1333195.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/14/WCF-Channel-Programming-Model-Example.html#Feedback</comments><slash:comments>14</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1333195.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1333195.html</trackback:ping><description><![CDATA[<h2>引言</h2> <p>从本质上说，WCF是一个通信服务框架，它允许我们使用不同的传输协议，使用不同的消息编码形式，跟不同的WS-*系列规范交互，而所有这些细节都是由通道堆栈来处理的。在《<a href="http://www.cnblogs.com/Terrylee/archive/2008/11/11/WCF-Channel-Programming-Model-Design.html">WCF专题系列（8）：深度通道编程模型Part 1—设计篇</a>》中，对于WCF中的通道模型有了深入的认识，本文中，我将通过实例来说明在通道模型中，服务端是如何接收消息，客户端是如何发送消息的。  <h2>服务端通道</h2> <p>本文将不使用WCF的编程模型，而直接利用通道模型来进行通信，这样有助于我们更进一步加深对服务端处理消息的认识，在服务端侦听并接收消息的第一步需要创建绑定，我们既可以使用WCF中内置的绑定或者使用自定义的绑定，如下代码所示，创建一个CustomBinding：<pre class="code"><span style="color: green">// 创建自定义绑定
</span><span style="color: #2b91af">BindingElement</span>[] bindingElements = <span style="color: blue">new </span><span style="color: #2b91af">BindingElement</span>[2];
bindingElements[0] = <span style="color: blue">new </span><span style="color: #2b91af">TextMessageEncodingBindingElement</span>();
bindingElements[1] = <span style="color: blue">new </span><span style="color: #2b91af">HttpTransportBindingElement</span>();

<span style="color: #2b91af">CustomBinding </span>binding = <span style="color: blue">new </span><span style="color: #2b91af">CustomBinding</span>(bindingElements);</pre><a href="http://11011.net/software/vspaste"></a>
<p>此处添加了HttpTransportBindingElement，所以生成的通道堆栈具有HTTP传输通道，另外采用了文本消息编码器。接下来调用刚才创建的CustomBinding的BuildChannelListener方法来构造通道侦听器，需要指定侦听基地址以及绑定参数，另外调用Open()方法打开通道监听器，相信大家一定还记得Open()方法是在接口ICommunicationObject中定义的，如下代码所示：<pre class="code"><span style="color: green">// 使用自定义绑定创建通道侦听器         
</span><span style="color: #2b91af">IChannelListener</span>&lt;<span style="color: #2b91af">IReplyChannel</span>&gt; listener =
      binding.BuildChannelListener&lt;<span style="color: #2b91af">IReplyChannel</span>&gt;(
         <span style="color: blue">new </span><span style="color: #2b91af">Uri</span>(<span style="color: #a31515">"http://localhost:8887/StringService"</span>),
         <span style="color: blue">new </span><span style="color: #2b91af">BindingParameterCollection</span>());

<span style="color: green">// 监听消息
</span>listener.Open();
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Listening for incoming channel connections"</span>);</pre><a href="http://11011.net/software/vspaste"></a>
<p>现在侦听传入的消息，由于我们使用请求了响应消息交换模式，此处侦听器返回一个实现了IReplyChannel的通道，为了在此通道上接收消息，我们首先对其调用Open()方法（该方法仍然是在ICommunicationObject中定义），以便将其置于一个准备进行通信的状态。 然后，我们调用ReceiveRequest()方法，它会处于阻止状态，直到消息达到，如下代码所示：<pre class="code"><span style="color: green">// 创建Reply通道
</span><span style="color: #2b91af">IReplyChannel </span>channel = listener.AcceptChannel();
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Channel accepted. Listening for messages"</span>);
channel.Open();

<span style="color: #2b91af">RequestContext </span>request = channel.ReceiveRequest();</pre><a href="http://11011.net/software/vspaste"></a>
<p>当ReceiveRequest()方法返回一个RequestContext时，再使用其RequestMessage属性获取接收到的消息。输出消息的操作（Action）和内容。为了发送答复，在此例中创建一个新的答复消息，它会将我们在请求中接收到的字符串数据，添加一段字符后再传递回去。然后，调用Reply()方法以发送答复消息，如下代码所示：<pre class="code"><span style="color: green">// 读取请求的消息
</span><span style="color: #2b91af">Message </span>message = request.RequestMessage;
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Message Received"</span>);
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Message Action: {0}"</span>, message.Headers.Action);
<span style="color: blue">string </span>body = message.GetBody&lt;<span style="color: blue">string</span>&gt;();
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Message Content: {0}"</span>, body);

<span style="color: green">// 发送响应消息
</span><span style="color: #2b91af">Message </span>replymessage = <span style="color: #2b91af">Message</span>.CreateMessage(
    binding.MessageVersion,
    <span style="color: #a31515">"http://www.cnblogs.com/TerryLee/Encode"</span>,
     <span style="color: #a31515">"Hello : " </span>+ body);

request.Reply(replymessage);</pre><a href="http://11011.net/software/vspaste"></a>
<p>最后别忘了做资源释放工作，关闭通道侦听器、通道、请求消息、请求上下文等，如下代码所示：<pre class="code"><span style="color: green">// 释放对象
</span>message.Close();
request.Close();
channel.Close();
listener.Close();</pre><a href="http://11011.net/software/vspaste"></a>
<p>完整的代码如下所示：<pre class="code"><span style="color: gray">/// &lt;summary&gt;
/// </span><span style="color: green">Author:TerryLee
</span><span style="color: gray">/// </span><span style="color: green">Url:http://www.cnblogs.com/terrylee
</span><span style="color: gray">/// &lt;/summary&gt;
</span><span style="color: blue">static void </span>Main()
{
    <span style="color: green">// 创建自定义绑定
    </span><span style="color: #2b91af">BindingElement</span>[] bindingElements = <span style="color: blue">new </span><span style="color: #2b91af">BindingElement</span>[2];
    bindingElements[0] = <span style="color: blue">new </span><span style="color: #2b91af">TextMessageEncodingBindingElement</span>();
    bindingElements[1] = <span style="color: blue">new </span><span style="color: #2b91af">HttpTransportBindingElement</span>();

    <span style="color: #2b91af">CustomBinding </span>binding = <span style="color: blue">new </span><span style="color: #2b91af">CustomBinding</span>(bindingElements);

    <span style="color: green">// 使用自定义绑定创建通道侦听器         
    </span><span style="color: #2b91af">IChannelListener</span>&lt;<span style="color: #2b91af">IReplyChannel</span>&gt; listener =
          binding.BuildChannelListener&lt;<span style="color: #2b91af">IReplyChannel</span>&gt;(
             <span style="color: blue">new </span><span style="color: #2b91af">Uri</span>(<span style="color: #a31515">"http://localhost:8887/StringService"</span>),
             <span style="color: blue">new </span><span style="color: #2b91af">BindingParameterCollection</span>());

    <span style="color: green">// 监听消息
    </span>listener.Open();
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Listening for incoming channel connections"</span>);

    <span style="color: green">// 创建Reply通道
    </span><span style="color: #2b91af">IReplyChannel </span>channel = listener.AcceptChannel();
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Channel accepted. Listening for messages"</span>);
    channel.Open();

    <span style="color: #2b91af">RequestContext </span>request = channel.ReceiveRequest();

    <span style="color: green">// 读取请求的消息
    </span><span style="color: #2b91af">Message </span>message = request.RequestMessage;
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Message Received"</span>);
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Message Action: {0}"</span>, message.Headers.Action);
    <span style="color: blue">string </span>body = message.GetBody&lt;<span style="color: blue">string</span>&gt;();
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Message Content: {0}"</span>, body);

    <span style="color: green">// 发送响应消息
    </span><span style="color: #2b91af">Message </span>replymessage = <span style="color: #2b91af">Message</span>.CreateMessage(
        binding.MessageVersion,
        <span style="color: #a31515">"http://www.cnblogs.com/TerryLee/Encode"</span>,
         <span style="color: #a31515">"Hello : " </span>+ body);

    request.Reply(replymessage);

    <span style="color: green">// 释放对象
    </span>message.Close();
    request.Close();
    channel.Close();
    listener.Close();

    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Press Enter to exit"</span>);
    <span style="color: #2b91af">Console</span>.ReadLine();
}</pre><a href="http://11011.net/software/vspaste"></a>
<p>现在运行服务端如图1所示，由于没有消息到达，所以ReceiveRequest()方法会阻塞： 
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="236" alt="TerryLee_WCF_31" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/WCF9Part2_243/TerryLee_WCF_31_3.png" width="561" border="0"> 
<p>图 1 
<h2>客户端通道</h2>
<p>前面完成了服务端的工作，接下来我们看看如何在客户端直接使用通道模型进行通信。与服务端一致，请求消息的第一步是创建绑定，因为双方需要通过绑定就通信的细节达成一致。创建自定义绑定与服务端一致，如下代码所示：<pre class="code"><span style="color: green">// 创建绑定
</span><span style="color: #2b91af">BindingElement</span>[] bindingElements = <span style="color: blue">new </span><span style="color: #2b91af">BindingElement</span>[2];
bindingElements[0] = <span style="color: blue">new </span><span style="color: #2b91af">TextMessageEncodingBindingElement</span>();
bindingElements[1] = <span style="color: blue">new </span><span style="color: #2b91af">HttpTransportBindingElement</span>();

<span style="color: #2b91af">CustomBinding </span>binding = <span style="color: blue">new </span><span style="color: #2b91af">CustomBinding</span>(bindingElements);</pre><a href="http://11011.net/software/vspaste"></a>
<p>接下来需要使用刚才创建的绑定来构造通道工厂，在上一篇中我们提到，消息的接收方使用通道侦听器，而消息的请求方使用通道工厂，这次使用BuildChannelFactory()方法构造通道工厂并打开，如下代码所示：<pre class="code"><span style="color: green">// 使用绑定创建通道工厂
</span><span style="color: #2b91af">IChannelFactory</span>&lt;<span style="color: #2b91af">IRequestChannel</span>&gt; factory =
binding.BuildChannelFactory&lt;<span style="color: #2b91af">IRequestChannel</span>&gt;(
                 <span style="color: blue">new </span><span style="color: #2b91af">BindingParameterCollection</span>());
<span style="color: green">// 打开通道工厂
</span>factory.Open();
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Channel factory opened"</span>);</pre><a href="http://11011.net/software/vspaste"></a>
<p>现在使用通道工厂的CreateChannel()方法来创建IRequestChannel，得到通道后，调用它的Open()方法以使其处于通信就绪状态，如下代码所示：<pre class="code"><span style="color: green">// 创建Request通道
</span><span style="color: #2b91af">IRequestChannel </span>channel = factory.CreateChannel(
   <span style="color: blue">new </span><span style="color: #2b91af">EndpointAddress</span>(<span style="color: #a31515">"http://localhost:8887/StringService"</span>));
channel.Open();
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Request channel opened"</span>);</pre><a href="http://11011.net/software/vspaste"></a>
<p>打开通道之后，就可以创建消息并使用通道的 Request()方法发送请求并等待响应，这里我们发送的消息内容是“TerryLee”，当此方法返回时，我们将能够得到回复消息，可以读取该消息以发现终结点回复的内容，如下代码所示：<pre class="code"><span style="color: green">// 创建请求消息
</span><span style="color: #2b91af">Message </span>requestmessage = <span style="color: #2b91af">Message</span>.CreateMessage(
    binding.MessageVersion,
    <span style="color: #a31515">"http://www.cnblogs.com/TerryLee/Encode"</span>,
     <span style="color: #a31515">"TerryLee"</span>);

<span style="color: green">// 发送请求消息并接收响应消息
</span><span style="color: #2b91af">Message </span>replymessage = channel.Request(requestmessage);
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Reply message received"</span>);
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Reply action: {0}"</span>,
                      replymessage.Headers.Action);
<span style="color: blue">string </span>data = replymessage.GetBody&lt;<span style="color: blue">string</span>&gt;();
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Reply content: {0}"</span>, data);</pre><a href="http://11011.net/software/vspaste"></a>
<p>最后仍然是资源释放工作，关闭通道工厂、通道以及请求消息，如下代码所示：<pre class="code">replymessage.Close();
channel.Close();
factory.Close();</pre><a href="http://11011.net/software/vspaste"></a>
<p>完整的客户端代码为：<pre class="code"><span style="color: gray">/// &lt;summary&gt;
/// </span><span style="color: green">Author:TerryLee
</span><span style="color: gray">/// </span><span style="color: green">Url:http://www.cnblogs.com/terrylee
</span><span style="color: gray">/// &lt;/summary&gt;
</span><span style="color: blue">public static void </span>Main()
{
    <span style="color: green">// 创建绑定
    </span><span style="color: #2b91af">BindingElement</span>[] bindingElements = <span style="color: blue">new </span><span style="color: #2b91af">BindingElement</span>[2];
    bindingElements[0] = <span style="color: blue">new </span><span style="color: #2b91af">TextMessageEncodingBindingElement</span>();
    bindingElements[1] = <span style="color: blue">new </span><span style="color: #2b91af">HttpTransportBindingElement</span>();

    <span style="color: #2b91af">CustomBinding </span>binding = <span style="color: blue">new </span><span style="color: #2b91af">CustomBinding</span>(bindingElements);

    <span style="color: green">// 使用绑定创建通道工厂
    </span><span style="color: #2b91af">IChannelFactory</span>&lt;<span style="color: #2b91af">IRequestChannel</span>&gt; factory =
    binding.BuildChannelFactory&lt;<span style="color: #2b91af">IRequestChannel</span>&gt;(
                     <span style="color: blue">new </span><span style="color: #2b91af">BindingParameterCollection</span>());
    <span style="color: green">// 打开通道工厂
    </span>factory.Open();
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Channel factory opened"</span>);

    <span style="color: green">// 创建Request通道
    </span><span style="color: #2b91af">IRequestChannel </span>channel = factory.CreateChannel(
       <span style="color: blue">new </span><span style="color: #2b91af">EndpointAddress</span>(<span style="color: #a31515">"http://localhost:8887/StringService"</span>));
    channel.Open();
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Request channel opened"</span>);

    <span style="color: green">// 创建请求消息
    </span><span style="color: #2b91af">Message </span>requestmessage = <span style="color: #2b91af">Message</span>.CreateMessage(
        binding.MessageVersion,
        <span style="color: #a31515">"http://www.cnblogs.com/TerryLee/Encode"</span>,
         <span style="color: #a31515">"TerryLee"</span>);

    <span style="color: green">// 发送请求消息并接收响应消息
    </span><span style="color: #2b91af">Message </span>replymessage = channel.Request(requestmessage);
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Reply message received"</span>);
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Reply action: {0}"</span>,
                          replymessage.Headers.Action);
    <span style="color: blue">string </span>data = replymessage.GetBody&lt;<span style="color: blue">string</span>&gt;();
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Reply content: {0}"</span>, data);

    replymessage.Close();
    channel.Close();
    factory.Close();

    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Press Enter to exit"</span>);
    <span style="color: #2b91af">Console</span>.ReadLine();
}</pre><a href="http://11011.net/software/vspaste"></a>
<p>最后运行时服务端如图2所示： 
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="266" alt="TerryLee_WCF_33" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/WCF9Part2_243/TerryLee_WCF_33_3.png" width="580" border="0">&nbsp; <p>图 2 
<p>客户端如图3所示： 
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="280" alt="TerryLee_WCF_32" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/WCF9Part2_243/TerryLee_WCF_32_3.png" width="580" border="0"> 
<p>图 3 
<h2>温故知新</h2>
<p>现在我们再回顾一下<a href="http://www.cnblogs.com/Terrylee/archive/2008/11/11/WCF-Channel-Programming-Model-Design.html">上一篇</a>中所讲的知识，通道对象模型是实现通道、通道侦听器和通道工厂所必需的一组核心接口。还提供一些基类以辅助自定义实现。可以看到通道模型中最重要的有三组接口：通道、通道侦听器和通道工厂。每个通道均实现一个或多个接口，称为通道形状接口或通道形状；通道侦听器负责侦听传入消息，即在消息的接收端，然后通过由通道侦听器创建的通道将这些消息传送到上面的层；通道工厂负责创建通道用于发送消息，即在消息的发送方，并在通道工厂关闭时，关闭通道工厂创建的所有通道。如图4所示： 
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="381" alt="TerryLee_WCF_24" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/WCF9Part2_243/TerryLee_WCF_24_3.png" width="494" border="0"> 
<p>图 4 
<p>对照本文的示例代码，相信大家对于图4能够有更深的认识。 
<h2>总结</h2>
<p>本文我们通过一个简单的示例介绍了在通道模型中服务端是如何接收消息以及客户端是如何发送消息的，希望对大家有所帮助。</p><img src ="http://www.cnblogs.com/Terrylee/aggbug/1333195.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47970/" target="_blank">19岁天才黑客发布首个iPhone 3GS破解软件</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>WCF后传系列（8）：深度通道编程模型Part 1—设计篇</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/11/WCF-Channel-Programming-Model-Design.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Tue, 11 Nov 2008 14:36:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/11/WCF-Channel-Programming-Model-Design.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1331035.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/11/WCF-Channel-Programming-Model-Design.html#Feedback</comments><slash:comments>35</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1331035.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1331035.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_wcf.png" alt=""/></div>从本质上说，WCF是一个通信服务框架，它允许我们使用不同的传输协议，使用不同的消息编码形式，跟不同的WS-*系列规范交互，而所有这些细节都是由通道堆栈来处理的。为了简化这些处理，在WCF中提供了两种模型，一是针对开发者的应用程序编程模型；二是用来通信的通道模型，这样对于开发者来说，只要了解应用程序编程模型就足够了，而不会涉及到通道模型，然而，对于通道模型进行必要的学习，可以让我们真正理解WCF中“通信”概念，了解WCF的 整个架构体系，从而构建出更加健壮的WCF服务或者对WCF框架进行扩展。在本文中，我们将进行深度了解WCF中的通道模型是如何设计的。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/11/11/WCF-Channel-Programming-Model-Design.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1331035.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47969/" target="_blank">新浪邮箱大本营粉墨登场！Sina.cn开放注册</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>回归Dos操作的快感，进入PowerShell世界</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/09/Windows-PowerShell-Overview.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Sat, 08 Nov 2008 17:23:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/09/Windows-PowerShell-Overview.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1329918.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/09/Windows-PowerShell-Overview.html#Feedback</comments><slash:comments>73</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1329918.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1329918.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_powershell.png" alt=""/></div>写下本篇文章源于参加Tech.Ed的一场关于Window PowerShell的课程。虽然之前也经常关注，但从没有亲自体验过。Windows PowerShell 是一种新的命令行外壳和脚本语言，用于进行系统管理和自动化任务，它建立在 .NET Framework 的基础上，可使 IT 专业人员和开发人员控制和自动完成Windows 和应用程序的管理。更为强大之处在于它可以调用.NET Framework中的类库，可以与COM、ADO、XML等交互。在本文中让我们一起来体会一下回归Doc操作的快感，进入强大无比的Windows PowerShell世界。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/11/09/Windows-PowerShell-Overview.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1329918.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47968/" target="_blank">IE市场份额首次跌破60%</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>WCF后传系列（7）：消息如何传递之绑定Part 2</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/06/WCF-Binding-Elements.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Thu, 06 Nov 2008 15:56:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/06/WCF-Binding-Elements.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1328513.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/06/WCF-Binding-Elements.html#Feedback</comments><slash:comments>16</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1328513.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1328513.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_wcf.png" alt=""/></div>在WCF专题系列（6）：消息如何传递之绑定Part 1一文中，我提到绑定由绑定元素组成，每个绑定元素用来描述终结点与客户端通信方式中的某个方面，在发送或接收消息时，每个绑定元素都表示一个处理步骤；运行时，绑定元素会创建必要的通道和侦听器，用以生成传出和传入通道堆栈。本文为消息如何传递之绑定第二部分，将详细介绍WCF内置的各种绑定元素，绑定元素之间的顺序以及如何创建一个自定义的绑定元素。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/11/06/WCF-Binding-Elements.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1328513.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47965/" target="_blank">Google App Engine宕机6小时——云的安全在哪里？</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>WCF后传系列（6）：消息如何传递之绑定Part 1</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/05/WCF-Binding-Overview.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Wed, 05 Nov 2008 14:44:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/05/WCF-Binding-Overview.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1327676.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/05/WCF-Binding-Overview.html#Feedback</comments><slash:comments>22</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1327676.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1327676.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_wcf.png" alt=""/></div>每个服务终结点都包含一个地址Address、一个绑定Binding 和一个契约Contract。契约指定可用的操作，绑定指定如何与服务进行通信，而地址指定查找服务的位置，在WCF专题系列前5篇中，深入了解了WCF中寻址的细节；从本文开始，将深入了解经典“ABC”中的B，即绑定Binding，了解它的原理，如何使用绑定通信以及在元数据中如何公开。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/11/05/WCF-Binding-Overview.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1327676.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47961/" target="_blank">微软新推社交网站Windows Live Planet</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>.NET Framework 4.0海报</title><link>http://www.cnblogs.com/Terrylee/archive/2008/10/31/dotnet-framework-v4-poster.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Thu, 30 Oct 2008 16:44:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/10/31/dotnet-framework-v4-poster.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1323378.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/10/31/dotnet-framework-v4-poster.html#Feedback</comments><slash:comments>27</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1323378.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1323378.html</trackback:ping><description><![CDATA[<p>在PDC 2008大会上，微软发布了一款非常漂亮的.NET Framework 4.0海报，在海报中展示了.NET Framework 3.5 SP1和.NET Framework 4中新添加的功能。同时还使用Silverlight 2技术开发了一个Deep Zoom的版本，可以在线预览，另外也可以下载PDF版本收藏。 <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="365" alt="TerryLee_0202" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/.NETFramework4.0_692/TerryLee_0202_3.png" width="541" border="0">  <p><a href="http://tinyurl.com/DotNetFramework4PosterDeepZoom">Deep Zoom在线版</a> <p><a href="http://tinyurl.com/PDC2008-NETFX4PDF">下载PDF版本</a></p><img src ="http://www.cnblogs.com/Terrylee/aggbug/1323378.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47960/" target="_blank">火狐3.5版被指推出太匆忙：存在50多个漏洞</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>WCF后传系列（5）：深入WCF寻址Part 5—逻辑地址和物理地址</title><link>http://www.cnblogs.com/Terrylee/archive/2008/10/31/WCF-Addressing-ListenUri-and-EndpointAddress.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Thu, 30 Oct 2008 16:16:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/10/31/WCF-Addressing-ListenUri-and-EndpointAddress.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1323370.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/10/31/WCF-Addressing-ListenUri-and-EndpointAddress.html#Feedback</comments><slash:comments>11</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1323370.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1323370.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_wcf.png" alt=""/></div>在WCF中，每个服务终结点都与两个地址相关联，一个逻辑地址和一个物理地址，逻辑地址就是SOAP消息的目标地址，即前面不止一次提到的“To”地址，而物理地址是WCF侦听器真正监听的地址。在WCF中，逻辑地址称之为终结点地址Endpoint Address，而物理地址则称之为监听地址ListenUri。

本文将详细介绍WCF中的物理地址和逻辑地址，以及如何使用tcpTrace来进行SOAP消息的跟踪。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/10/31/WCF-Addressing-ListenUri-and-EndpointAddress.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1323370.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47960/" target="_blank">火狐3.5版被指推出太匆忙：存在50多个漏洞</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>WCF后传系列（4）：深入WCF寻址Part 4—自定义消息筛选器</title><link>http://www.cnblogs.com/Terrylee/archive/2008/10/30/WCF-Addressing-Part3-Customize-Message-Filter.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Wed, 29 Oct 2008 16:44:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/10/30/WCF-Addressing-Part3-Customize-Message-Filter.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1322616.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/10/30/WCF-Addressing-Part3-Customize-Message-Filter.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1322616.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1322616.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_wcf.png" alt=""/></div>在WCF专题系列（3）：深入WCF寻址Part 3—消息过滤引擎一文中，详细介绍了WCF中的消息筛选引擎，包括消息筛选器和筛选器表，每个EndpointDispatcher都包含了两个消息筛选器，默认的地址过滤器是EndpointAddressMessageFilter，默认的契约过滤器是ActionMessageFilter，这些是可以通过Behavior来改变的。本文我们将学习如何创建一个自定义的消息过滤器，并通过自定义Behavior来改变EndpointDispatcher的默认过滤器。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/10/30/WCF-Addressing-Part3-Customize-Message-Filter.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1322616.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47959/" target="_blank">Google对手机搜索进行优化升级</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>Silverlight Toolkit预览Part 1：介绍</title><link>http://www.cnblogs.com/Terrylee/archive/2008/10/29/Silverlight-Toolkit-overview-part1.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Tue, 28 Oct 2008 18:06:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/10/29/Silverlight-Toolkit-overview-part1.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1321780.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/10/29/Silverlight-Toolkit-overview-part1.html#Feedback</comments><slash:comments>42</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1321780.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1321780.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_silverlight2.gif" alt=""/></div>Silverlight Toolkit是由微软提供的一系列的Silverlight控件、组件和工具的集合，不仅免费且完全开源，当前发布的版本中包括12个控件和6套非常酷的主题样式，覆盖的范围包括图表、样式、布局以及用户输入，效果预览：&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/10/29/Silverlight-Toolkit-overview-part1.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1321780.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47958/" target="_blank">风声又起 Windows 7 RTM版7月13日完成</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>微软发布Enterprise Library 4.1和Unity 1.2</title><link>http://www.cnblogs.com/Terrylee/archive/2008/10/29/enterprise-library-v-4-1-and-unity-application-block-v-1-2-Released.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Tue, 28 Oct 2008 16:58:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/10/29/enterprise-library-v-4-1-and-unity-application-block-v-1-2-Released.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1321774.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/10/29/enterprise-library-v-4-1-and-unity-application-block-v-1-2-Released.html#Feedback</comments><slash:comments>15</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1321774.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1321774.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_pandp.png" alt=""/></div>微软模式与实践团队今天发布了Enterprise Library 4.1和Unity 1.2版本，这次发布的主要新特性如下：

1. 支持Visual Studio 2008 SP1

2. Unity应用程序块中加入了拦截机制

3. 性能提升

4. 配置工具的可用性提升

5. Bugs修复。

在Unity 1.2中有如下几点改进：

1. 简化了对象的创建，尤其是层次对象的结构和依赖

2. 通过为容器推迟组件的配置增加了灵活性

3. 服务定位能力增强，允许客户存储或者缓存容器

4. 实例和类型拦截&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/10/29/enterprise-library-v-4-1-and-unity-application-block-v-1-2-Released.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1321774.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47958/" target="_blank">风声又起 Windows 7 RTM版7月13日完成</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item></channel></rss>