﻿<?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-随笔分类-[01]&amp;nbsp;&amp;nbsp;.NET大本营</title><link>http://www.cnblogs.com/Terrylee/category/48779.html</link><description>TerryLee技术专栏</description><language>zh-cn</language><lastBuildDate>Sun, 19 Apr 2009 18:42:36 GMT</lastBuildDate><pubDate>Sun, 19 Apr 2009 18:42:36 GMT</pubDate><ttl>60</ttl><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>0</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" />]]></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>27</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" />]]></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" />]]></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" />]]></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[摘要: 在PDC2008大会上，微软发布了一款非常漂亮的.NETFramework4.0海报，在海报中展示了.NETFramework3.5SP1和.NETFramework4中新添加的功能。...&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/10/31/dotnet-framework-v4-poster.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1323378.html?type=1" width = "1" height = "1" />]]></description></item><item><title>Managed Extensibility Framework在Codeplex上开放全部源码</title><link>http://www.cnblogs.com/Terrylee/archive/2008/09/08/microsoft-extensibility-framework-released-on-codeplex.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Sun, 07 Sep 2008 16:29:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/09/08/microsoft-extensibility-framework-released-on-codeplex.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1286462.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/09/08/microsoft-extensibility-framework-released-on-codeplex.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1286462.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1286462.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>就在几天前，我写了一篇关于Managed Extensibility Framework（MEF）的文章《使用Managed Extensibility Framework方便的扩展应用程序》，有一位朋友提到MEF为什么不在codeplex上，而当时我的回答是不放在Codeplex上是因为它现在还不开源，所以只能放在http://code.msdn.microsoft.com上了。然而，还不到一周的时间，微软就在Codeplex上开放了全部的源码，以及相关的文档等。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/09/08/microsoft-extensibility-framework-released-on-codeplex.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1286462.html?type=1" width = "1" height = "1" />]]></description></item><item><title>使用Managed Extensibility Framework方便的扩展应用程序</title><link>http://www.cnblogs.com/Terrylee/archive/2008/09/01/uisng-managed-extensibility-framework-overview.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Sun, 31 Aug 2008 16:21:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/09/01/uisng-managed-extensibility-framework-overview.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1280768.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/09/01/uisng-managed-extensibility-framework-overview.html#Feedback</comments><slash:comments>41</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1280768.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1280768.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>Managed Extensibility Framework（MEF）是.NET平台下的一个扩展性管理框架，它是一系列特性的集合，包括依赖注入（DI）以及Duck Typing等。MEF为开发人员提供了一个工具，让我们可以轻松的对应用程序进行扩展并且对已有的代码产生最小的影响，开发人员在开发过程中根据功能要求定义一些扩展点，之后扩展人员就可以使用这些扩展点与应用程序交互；同时MEF让应用程序与扩展程序之间不产生直接的依赖，这样也允许在多个具有同样的扩展需求之间共享扩展程序。
<br/><br/>
本文将介绍一下Managed Extensibility Framework的一些基本使用。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/09/01/uisng-managed-extensibility-framework-overview.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1280768.html?type=1" width = "1" height = "1" />]]></description></item><item><title>使用.NET Framework中新的日期时间类型</title><link>http://www.cnblogs.com/Terrylee/archive/2008/08/29/using-net-framework-new-datetime-data-type.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Fri, 29 Aug 2008 15:13:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/08/29/using-net-framework-new-datetime-data-type.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1279825.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/08/29/using-net-framework-new-datetime-data-type.html#Feedback</comments><slash:comments>27</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1279825.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1279825.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>写下本文缘于前几天博客园一位朋友发表了一篇.NET面试题的文章，其中一个关于DateTime的问题引起了大家激烈的争论，鉴于日期时间类型是大家开发中会频繁使用的一个中数据类型，这里我们有必要来对.NET Framework中的日期时间类型做一个深入的认识。
<br/>
<br/>
本文我们将对DateTime，DateTimeOffset，TimeZone，TimeZoneInfo等类型进行讨论。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/08/29/using-net-framework-new-datetime-data-type.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1279825.html?type=1" width = "1" height = "1" />]]></description></item><item><title>.NET Framework终于开源了！</title><link>http://www.cnblogs.com/Terrylee/archive/2008/01/17/net-framework-source-code-now-available.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Thu, 17 Jan 2008 00:50:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/01/17/net-framework-source-code-now-available.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1042263.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/01/17/net-framework-source-code-now-available.html#Feedback</comments><slash:comments>106</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1042263.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1042263.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_dotnet.gif" alt="05"/></div>期待已久的.NET Framework终于在本周开源了，微软在MS-RL协议下终于公开了.NET Framework源代码，我们只可以自由查看，不允许直接进行修改。第一批开放的源代码包括：<br><br>.NET基本类库<br>ASP.NET<br>Windows Forms<br>Windows Presentation Foundation<br>ADO.NET和 XML&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/01/17/net-framework-source-code-now-available.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1042263.html?type=1" width = "1" height = "1" />]]></description></item><item><title>ASP.NET 3.5 Extensions预览版即将发布</title><link>http://www.cnblogs.com/Terrylee/archive/2007/11/30/aspnet-extensions-preview-and-silverlight-v2.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Fri, 30 Nov 2007 04:55:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2007/11/30/aspnet-extensions-preview-and-silverlight-v2.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/978152.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2007/11/30/aspnet-extensions-preview-and-silverlight-v2.html#Feedback</comments><slash:comments>17</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/978152.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/978152.html</trackback:ping><description><![CDATA[摘要: 从Scott Guthrie的博客上得知，下星期微软即将发布ASP.NET 3.5 Extensions预览版。在ASP.NET 3.5 Extensions中将会提供：<br>ASP.NET MVC框架<br>ASP.NET AJAX改进<br>ASP.NET动态数据支持<br>ASP.NET Silverlight支持<br>ADO.NET Data Services&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2007/11/30/aspnet-extensions-preview-and-silverlight-v2.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/978152.html?type=1" width = "1" height = "1" />]]></description></item><item><title>Enterprise Library 3.0 December 2006 CTP版发布了！</title><link>http://www.cnblogs.com/Terrylee/archive/2006/12/23/Enterprise_Library_3_December_2006_CTP.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Sat, 23 Dec 2006 07:14:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/12/23/Enterprise_Library_3_December_2006_CTP.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/601405.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/12/23/Enterprise_Library_3_December_2006_CTP.html#Feedback</comments><slash:comments>21</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/601405.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/601405.html</trackback:ping><description><![CDATA[摘要: 刚刚从Tom Hollander看到消息，Enterprise Library 3.0 December 2006 CTP版发布了！这是Enterprise Library 3.0发布的第一个版本，同时该项目也移到了Codeplex上，官方主页为：http://www.codeplex.com/entlib。<br><br>点击这里下载Enterprise Library v.0 December 2006 CTP版，这次发布的内容包括以前提到的验证应用程序块、数据访问应用程序块、应用程序块软件工厂等，详细内容如下所示<br>&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/12/23/Enterprise_Library_3_December_2006_CTP.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/601405.html?type=1" width = "1" height = "1" />]]></description></item><item><title>Visual Studio 2005 Service Pack 1 正式版发布</title><link>http://www.cnblogs.com/Terrylee/archive/2006/12/15/Visual_Studio_2005_Service_Pack_1.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Fri, 15 Dec 2006 08:41:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/12/15/Visual_Studio_2005_Service_Pack_1.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/593484.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/12/15/Visual_Studio_2005_Service_Pack_1.html#Feedback</comments><slash:comments>31</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/593484.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/593484.html</trackback:ping><description><![CDATA[摘要: 据Darryl Burling在个人Blog里宣布，Visual Studio 2005 Service Pack 1将于明天发布，现在已经可以下载了，详细的信息大家可以访问<a href="http://msdn.microsoft.com/vstudio/support/vs2005sp1/default.aspx">Visual Studio支持中心</a>。<br><br>相关下载<br><br>Visual Studio 2005 Team Suite SP1 (includes SP1 updates for Standard, Professional, and Team Editions of Visual Studio 2005) <br><br>Visual Studio 2005 Team Foundation Server SP1 <br><br>Visual Studio 2005 Express Editions SP1 <br><br>Visual Studio 2005 SP1 Update for Windows Vista Bet&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/12/15/Visual_Studio_2005_Service_Pack_1.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/593484.html?type=1" width = "1" height = "1" />]]></description></item><item><title>一款很有趣的开源VS2005插件：CopySourceAsHtml</title><link>http://www.cnblogs.com/Terrylee/archive/2006/11/28/Visual_Studio_2005_Add_In_CopySourceAsHtml.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Tue, 28 Nov 2006 00:38:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/11/28/Visual_Studio_2005_Add_In_CopySourceAsHtml.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/574635.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/11/28/Visual_Studio_2005_Add_In_CopySourceAsHtml.html#Feedback</comments><slash:comments>24</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/574635.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/574635.html</trackback:ping><description><![CDATA[摘要: CopySourceAsHtml是一款能够以HTML格式拷贝源代码的Visual Studio 2005插件，拷贝后它会保持原有的高亮显示，这样代码在浏览器中和IDE编辑器中看起来是一样的。下载安装后它会在右键菜单中出现一项Copy As Html，有如下这样一段代码：<br><br>在IDE编辑器中，选择代码并点击右键选择Copy As Html<br><br>粘贴到ASPX页面中，运行<br><br>下载：  安装包     源代码<br><br>详情可以访问：http://www.jtleigh.com/people/colin/software/CopySourceAsHtml/<br>&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/11/28/Visual_Studio_2005_Add_In_CopySourceAsHtml.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/574635.html?type=1" width = "1" height = "1" />]]></description></item><item><title>微软Code Snippet Designer Alpha版发布了</title><link>http://www.cnblogs.com/Terrylee/archive/2006/11/18/Microsoft_Code_Snippet_Designer.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Sat, 18 Nov 2006 06:45:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/11/18/Microsoft_Code_Snippet_Designer.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/564544.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/11/18/Microsoft_Code_Snippet_Designer.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/564544.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/564544.html</trackback:ping><description><![CDATA[摘要: 大家对于VS2005中的Code Snippet都不陌生了，如果我们要创建自定义的Code Snippets，可以使用文本编辑器新建后缀名为snippet的XML文件进行编辑，或者使用微软提供的Snippet编辑器去编辑Code Snippet。最近微软发布了一个<a href="http://download.microsoft.com/download/6/7/7/677b3a55-6a61-433f-ae26-6d55aa16b0f8/Microsoft%20Snippet%20Designer%20(Alpha).msi">Code Snippet Designer</a>，可以很方便的集成在VS2005，进行Code Snippet的编辑，现在还处于Alpha版本。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/11/18/Microsoft_Code_Snippet_Designer.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/564544.html?type=1" width = "1" height = "1" />]]></description></item><item><title>IronPython for ASP.NET：使用IronPython创建一个简单的Web页面</title><link>http://www.cnblogs.com/Terrylee/archive/2006/11/04/Creating_a_Basic_Web_Page_with_IronPython.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Fri, 03 Nov 2006 16:36:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/11/04/Creating_a_Basic_Web_Page_with_IronPython.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/549633.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/11/04/Creating_a_Basic_Web_Page_with_IronPython.html#Feedback</comments><slash:comments>19</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/549633.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/549633.html</trackback:ping><description><![CDATA[摘要: <a href="http://www.cnblogs.com/Terrylee/archive/2006/11/03/IronPython_For_ASPNET_CTP.html">IronPython for ASP.NET CTP版发布</a>的消息无疑让人激动，我也迫不及待的下载下来体验一下，根据提供的入门教程写一个最基本的Web页面。在开始之前，你需要<a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=55932211-0D7E-4C6E-9B18-8F9D2AC1EE43&displaylang=en">下载安装IronPython for ASP.NET CTP版</a>。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/11/04/Creating_a_Basic_Web_Page_with_IronPython.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/549633.html?type=1" width = "1" height = "1" />]]></description></item><item><title>Enterprise Library 2.0 Hands On Lab 翻译</title><link>http://www.cnblogs.com/Terrylee/archive/2006/10/16/Enterprise_Library_Hands_On_Lab.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Mon, 16 Oct 2006 15:15:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/10/16/Enterprise_Library_Hands_On_Lab.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/522337.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/10/16/Enterprise_Library_Hands_On_Lab.html#Feedback</comments><slash:comments>23</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/522337.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/522337.html</trackback:ping><description><![CDATA[摘要: 有很多朋友来信问我为什么没有继续写Enterprise Library 2.0 Step By Step系列，这主要是由于个人工作原因，没有充足的时间去写相关的示例，所以就不能像1.1那样写的那么详细。在国庆假期里，正好有一点时间，于是我就翻译了这套Enterprise Library 2.0 Hands On Lab，作为两节的礼物送给初学的朋友，希望可以为初学者提供一点帮助，里面的示例相对来说都比较简单，如果能按照其中的步骤去完成每一个练习，就算以前没接触过Enterprise Library，相信也能很快地入门。<br><br>由于翻译的比较急，有很多地方都没有按照原文的意思去翻，更多地加入了我个人的一点见解，有疏漏的地方希望大家谅解。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/10/16/Enterprise_Library_Hands_On_Lab.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/522337.html?type=1" width = "1" height = "1" />]]></description></item><item><title>Atlas学习手记系列</title><link>http://www.cnblogs.com/Terrylee/archive/2006/09/01/atlas_series_articles.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Fri, 01 Sep 2006 00:51:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/09/01/atlas_series_articles.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/469950.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/09/01/atlas_series_articles.html#Feedback</comments><slash:comments>72</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/469950.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/469950.html</trackback:ping><description><![CDATA[摘要: Atlas作为.NET平台下的一种Ajax框架，从出现发展到现在，其间经历了很多个CTP版本，虽然直到现在还没有发布正式版本，却已经成为了.NET下的最强大的Ajax框架。本学习手记系列将作为我个人学习Atlas的总结，同时也记录了学习的过程，本文会不断更新。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/09/01/atlas_series_articles.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/469950.html?type=1" width = "1" height = "1" />]]></description></item><item><title>PetShop 4.0讨论专贴（Q&amp;A）</title><link>http://www.cnblogs.com/Terrylee/archive/2006/08/31/Dotnet_PetShop_4.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Thu, 31 Aug 2006 10:09:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/08/31/Dotnet_PetShop_4.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/491608.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/08/31/Dotnet_PetShop_4.html#Feedback</comments><slash:comments>37</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/491608.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/491608.html</trackback:ping><description><![CDATA[摘要: 根据fangyifeng这位朋友的意见，特开设此PetShop4.0讨论专贴，除了推荐一些关于PetShop4.0的不错的文章之外，也对大家平时遇到的问题作一下整理。&nbsp;一．园子里相关...&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/08/31/Dotnet_PetShop_4.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/491608.html?type=1" width = "1" height = "1" />]]></description></item><item><title>Enterprise Library系列文章回顾与总结</title><link>http://www.cnblogs.com/Terrylee/archive/2006/08/01/Enterprise_Library.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Tue, 01 Aug 2006 00:35:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/08/01/Enterprise_Library.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/464591.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/08/01/Enterprise_Library.html#Feedback</comments><slash:comments>150</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/464591.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/464591.html</trackback:ping><description><![CDATA[摘要: 自Enterprise Library 1.1 推出以来，Terry写了一系列的关于Enterprise Library的文章，其中得到了很多朋友的支持，在这里一并表示感谢。为了方便大家的阅读，这里我做了一下整理与分类。<br><br>&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/08/01/Enterprise_Library.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/464591.html?type=1" width = "1" height = "1" />]]></description></item><item><title>Atlas学习手记（9）：异步调用Page Method</title><link>http://www.cnblogs.com/Terrylee/archive/2006/07/31/Atlas_Calling_PageMethod.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Mon, 31 Jul 2006 03:17:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/07/31/Atlas_Calling_PageMethod.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/463843.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/07/31/Atlas_Calling_PageMethod.html#Feedback</comments><slash:comments>30</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/463843.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/463843.html</trackback:ping><description><![CDATA[摘要: 使用Atlas我们可以调用两种服务端的方法WebService Method和Page Method，在前面的使用中，我们一直都是调用WebService Method，如何去调用一个Page Method？本文将简单的介绍一下这一内容。<br><br><b>主要内容</b><br><br>1．如何调用Page Method<br><br>2．与WebService Method区别<br><br>&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/07/31/Atlas_Calling_PageMethod.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/463843.html?type=1" width = "1" height = "1" />]]></description></item><item><title>Atlas学习手记（8）：调用本地Web Service简单介绍</title><link>http://www.cnblogs.com/Terrylee/archive/2006/07/30/Atlas_WebService_Introduction.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Sun, 30 Jul 2006 05:56:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/07/30/Atlas_WebService_Introduction.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/463330.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/07/30/Atlas_WebService_Introduction.html#Feedback</comments><slash:comments>25</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/463330.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/463330.html</trackback:ping><description><![CDATA[摘要: Atlas对于调用WebService作了很好的封装，使得我们用JS调用WebService的工作变得非常的简单，只需要使用WebServiceName.WebMethod()就可以完成调用。本文...&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/07/30/Atlas_WebService_Introduction.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/463330.html?type=1" width = "1" height = "1" />]]></description></item><item><title>Atlas学习手记（7）：使用DragOverlayExtender实现拖放功能</title><link>http://www.cnblogs.com/Terrylee/archive/2006/07/30/Atlas_DragOverlayExtender.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Sun, 30 Jul 2006 02:53:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/07/30/Atlas_DragOverlayExtender.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/463234.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/07/30/Atlas_DragOverlayExtender.html#Feedback</comments><slash:comments>34</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/463234.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/463234.html</trackback:ping><description><![CDATA[摘要: DragOverlayExtender允许我们对任何控件添加类似于Drag-and-Drop Behaviors那样的拖放（Drag-and-Drop）功能，更重要的是如果要对已经存在的控件添加，我们不需要对原有控件做任何的改动，只需添加一个DragOverlayExtender就可以轻松实现。<br><br><b>主要内容</b><br><br>1．DragOverlayExtender介绍<br><br>2．完整示例<br><br>3．使用ProfileScriptService控件<br><br>运行效果：<br><br><img src="http://www.cnblogs.com/images/cnblogs_com/terrylee/Atlas_15.gif">&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/07/30/Atlas_DragOverlayExtender.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/463234.html?type=1" width = "1" height = "1" />]]></description></item><item><title>Atlas学习手记（6）：使用Atlas UpdateProgress控件</title><link>http://www.cnblogs.com/Terrylee/archive/2006/07/29/Atlas_UpdateProgress.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Sat, 29 Jul 2006 04:03:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/07/29/Atlas_UpdateProgress.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/462658.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/07/29/Atlas_UpdateProgress.html#Feedback</comments><slash:comments>47</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/462658.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/462658.html</trackback:ping><description><![CDATA[摘要: 在页面上执行较长时间的操作时，如果能够给用户提供一个类似于浏览器状态栏那样的进度条，将会使界面用户界面更加友好。在Atlas中，为我们提供的UpdateProgress控件可以轻松的实现这些。<br><br><b>主要内容</b><br><br>1．UpdateProgress控件介绍<br><br>2．完整的示例<br><br>运行效果：<br><br><img src="http://www.cnblogs.com/images/cnblogs_com/terrylee/Atlas_17.gif">&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/07/29/Atlas_UpdateProgress.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/462658.html?type=1" width = "1" height = "1" />]]></description></item><item><title>Atlas学习手记（5）：使用服务端定时控件TimerControl</title><link>http://www.cnblogs.com/Terrylee/archive/2006/07/28/Atlas_TimerControl.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Fri, 28 Jul 2006 09:39:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/07/28/Atlas_TimerControl.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/462349.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/07/28/Atlas_TimerControl.html#Feedback</comments><slash:comments>41</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/462349.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/462349.html</trackback:ping><description><![CDATA[摘要: TimerControl是一个用于服务器端定时器的控件，可用来实时显示数据等，在很多地方都有应用，本文将简单介绍一下TimerControl的使用。<br><br><b>主要内容</b><br><br>1．TimerControl介绍<br><br>2．完整示例<br><br>&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/07/28/Atlas_TimerControl.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/462349.html?type=1" width = "1" height = "1" />]]></description></item><item><title>Atlas学习手记（4）：使用AutoComplete Extender实现自动完成功能</title><link>http://www.cnblogs.com/Terrylee/archive/2006/07/27/Atlas_AutoCompleteExtender.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Thu, 27 Jul 2006 11:31:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/07/27/Atlas_AutoCompleteExtender.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/461339.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/07/27/Atlas_AutoCompleteExtender.html#Feedback</comments><slash:comments>90</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/461339.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/461339.html</trackback:ping><description><![CDATA[摘要: 自动完成功能在Ajax时代已经见的很多了，像Google Suggest，很多邮箱中也都有应用。在Atlas对于自动完成功能提供了很好的支持，提供了客户端的AutoComplete Behavior和服务器端的AutoComplete Extender的支持。本文主要看一下使用AutoComplete Extender来实现自动完成功能。<br><br><b>主要内容</b><br><br>1．AutoComplete Extender介绍<br><br>2．一个完整的示例<br><br>运行效果：<br><img src="http://www.cnblogs.com/images/cnblogs_com/terrylee/Atlas_11.jpg">&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/07/27/Atlas_AutoCompleteExtender.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/461339.html?type=1" width = "1" height = "1" />]]></description></item><item><title>Atlas学习手记（3）：由UpdatePanel开始</title><link>http://www.cnblogs.com/Terrylee/archive/2006/07/27/Atlas_UpdatePanel.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Thu, 27 Jul 2006 04:48:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/07/27/Atlas_UpdatePanel.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/460934.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/07/27/Atlas_UpdatePanel.html#Feedback</comments><slash:comments>42</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/460934.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/460934.html</trackback:ping><description><![CDATA[摘要: UpdatePanel是Atlas中一个很重要的控件，功能强大且容易使用，可以使我们只做很小的改动就可以向已有的ASP.NET站点添加Ajax。采用Dflying的建议，我也是由UpdatePanel进入Atlas的世界。本文将通过可视化和代码两种方式来实现向已有的ASP.NET应用程序中添加UpdatePanel。<br><br><b>主要内容</b><br><br>1．UpdatePanel概述<br><br>2．使用可视化方式<br><br>3．使用代码方式<br>&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/07/27/Atlas_UpdatePanel.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/460934.html?type=1" width = "1" height = "1" />]]></description></item><item><title>Atlas学习手记（2）：全面了解ScriptManager</title><link>http://www.cnblogs.com/Terrylee/archive/2006/07/26/Atlas_ScriptManager.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Wed, 26 Jul 2006 05:04:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/07/26/Atlas_ScriptManager.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/460024.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/07/26/Atlas_ScriptManager.html#Feedback</comments><slash:comments>27</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/460024.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/460024.html</trackback:ping><description><![CDATA[摘要: ScriptManager是Atlas一个重要的控件，它用来处理页面上的所有Atlas组件以及局部页面的更新，生成相关的客户端脚本，所有需要支持Atlas的ASP.NET页面上有且只能有一个ScriptManager控件。在ScriptManager控件中我们可以指定需要的脚本库，或者指定通过JS来调用的Web Service，还可以指定页面错误处理等。<br><br><b>主要内容</b><br><br>1．概述<br><br>2．Script Management<br><br>3．Web Service References<br><br>4．Error Handling<br><br>5．ScriptManagerProxy<br>&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/07/26/Atlas_ScriptManager.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/460024.html?type=1" width = "1" height = "1" />]]></description></item><item><title>Atlas学习手记（1）：Hello，Atlas</title><link>http://www.cnblogs.com/Terrylee/archive/2006/07/25/459518.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Tue, 25 Jul 2006 10:09:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/07/25/459518.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/459518.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/07/25/459518.html#Feedback</comments><slash:comments>90</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/459518.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/459518.html</trackback:ping><description><![CDATA[摘要: 关于Atlas的介绍已经有很多的文章，我就不废话了，对于我自己来说学习一个新东西，总是习惯于以一个简单的示例开始，Atlas也不例外，本文将会以一个非常简单的示例来踏上Atlas之旅，文中示例程序来自...&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/07/25/459518.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/459518.html?type=1" width = "1" height = "1" />]]></description></item><item><title>.NET设计模式系列文章</title><link>http://www.cnblogs.com/Terrylee/archive/2006/07/17/334911.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Mon, 17 Jul 2006 10:29:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/07/17/334911.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/334911.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/07/17/334911.html#Feedback</comments><slash:comments>310</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/334911.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/334911.html</trackback:ping><description><![CDATA[摘要: .NET设计模式系列，共分为30章，本部分内容不断更新中。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/07/17/334911.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/334911.html?type=1" width = "1" height = "1" />]]></description></item><item><title>Enterprise Library 2.0 技巧（4）：如何用编程的方法来配置Logging Application Block</title><link>http://www.cnblogs.com/Terrylee/archive/2006/07/08/enterprise_library2_4.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Sat, 08 Jul 2006 04:52:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2006/07/08/enterprise_library2_4.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/445845.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2006/07/08/enterprise_library2_4.html#Feedback</comments><slash:comments>17</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/445845.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/445845.html</trackback:ping><description><![CDATA[摘要: 在本系列的<a href="http://terrylee.cnblogs.com/archive/2006/07/03/enterprise_library2_1.html">技巧（1）</a>和<a href="http://terrylee.cnblogs.com/archive/2006/07/03/enterprise_library2_1.html">技巧（2）</a>中分别介绍了使用外部配置文件，使用数据库记录配置信息两种方法，不知道大家有没有想过不使用任何配置文件，也不使用数据库而直接用编程的方法来实现呢？本文将会展示如何使用编程的方法来配置Logging Application Block。<br><br><b>主要内容</b><br><br>1.几个重要的对象<br><br>2.示例代码<br>&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2006/07/08/enterprise_library2_4.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/445845.html?type=1" width = "1" height = "1" />]]></description></item></channel></rss>