如何为 Velocity 创建一个简单的 Enterprise Library 缓存管理器提供程序
本文介绍了如何使用 Application Block Software Factory 创建一个简单的 Velocity 缓存管理器提供程序。
引言
本文包含一个配方,用于使用 Application Block Software Factory 创建一个简单的 Velocity 缓存管理器提供程序。
创建项目
首先要做的是创建项目。
如果您的计算机上没有安装 Application Block Software Factory,您可以阅读我写的一篇 旧帖子 来安装它。
在 VS2008 中,选择 Guidance Packages -> Application Block Software Factory 项目类型,并在其中选择 Provider Library 模板,如下图所示

当出现 Create New Provider Library 表单时,填写相关详细信息并按 Finish 按钮

创建 Velocity 缓存管理器提供程序
生成项目后,下一步是创建 Velocity Cache Manager 提供程序。首先添加对 Caching Application Block 的引用。之后,右键单击 VelocityCacheProvider
类库项目,并在 Application Block Software Factory 菜单中选择 New Provider (Typed) 菜单项

这将打开 New Provider 向导。
填写以下详细信息
- 名称 -
VelocityCacheManager
(提供程序名称) - 提供程序接口 -
ICacheManager
(提供程序实现的接口) - 提供程序基类 -
ICacheManager
(提供程序扩展的基类) - 配置基类 -
CustomCacheManagerData
(帮助创建新的VelocityCacheManager
类的配置类)
完成后,向导应如下所示

按 Finish 按钮创建提供程序。
Velocity 缓存管理器实现
添加对 CacheBaseLibrary
和 ClientLibary
DLL 的引用,这些 DLL 位于 Velocity 部署目录中。
以下是 VelocityCacheManager
的实现
using Microsoft.Data.Caching;
using Microsoft.Practices.EnterpriseLibrary.Caching.Velocity.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
namespace Microsoft.Practices.EnterpriseLibrary.Caching.Velocity
{
[ConfigurationElementType(typeof(VelocityCacheManagerData))]
public class VelocityCacheManager : ICacheManager
{
#region Consts
private const string DefaultRegionName = "default";
#endregion
#region Members
private DataCache _realCache;
#endregion
#region Ctor
/// <summary>
/// <para>Initializes a new instance of the <see
/// cref="VelocityCacheManager"/>.</para>
/// </summary>
/// <param name="configuration">The configuration object
/// used to set the runtime values</param>
public VelocityCacheManager(VelocityCacheManagerData configuration)
{
var servers = CreateCacheEndpoints(configuration);
var factory = new DataCacheFactory
(servers, configuration.RoutingClient, configuration.LocalCache);
_realCache = factory.GetCache(configuration.NamedCache);
}
#endregion
#region Methods
private static DataCacheServerEndpoint[] CreateCacheEndpoints(
VelocityCacheManagerData configuration)
{
var servers = new DataCacheServerEndpoint[1];
servers[0] = new DataCacheServerEndpoint(configuration.HostName,
configuration.CachePort, configuration.CacheHostName);
return servers;
}
#endregion
#region ICacheManager Members
public void Add(string key, object value, CacheItemPriority scavengingPriority,
ICacheItemRefreshAction refreshAction, params ICacheItemExpiration[] expirations)
{
// other parameters are currently ignored
_realCache.Add(key, value);
}
public void Add(string key, object value)
{
_realCache.Add(key, value);
}
public bool Contains(string key)
{
object obj = _realCache.Get(key);
return obj != null;
}
public int Count
{
get
{
int counter = 0;
foreach (var item in _realCache.GetObjectsInRegion("default"))
{
counter++;
}
return counter;
}
}
public void Flush()
{
_realCache.ClearRegion(DefaultRegionName);
}
public object GetData(string key)
{
return _realCache.Get(key);
}
public void Remove(string key)
{
_realCache.Remove(key);
}
public object this[string key]
{
get
{
return _realCache.Get(key);
}
}
#endregion
}
}
以下是 VelocityCacheManagerData
的实现
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Caching.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder;
using Microsoft.Practices.ObjectBuilder2;
namespace Microsoft.Practices.EnterpriseLibrary.Caching.Velocity.Configuration
{
/// <summary>
/// Represents the configuration data for a <see
/// cref="VelocityCacheManager"/>.
/// </summary>
[Assembler(typeof(VelocityCacheManagerAssembler))]
public class VelocityCacheManagerData : CustomCacheManagerData
{
#region Consts
private const string RoutingClientString = "RoutingClient";
private const string LocalCacheString = "LocalCache";
private const string HostNameString = "HostName";
private const string CachePortString = "CachePort";
private const string CacheHostNameString = "CacheHostName";
private const string NamedCacheString = "NamedCache";
#endregion
#region Ctor
/// <summary>
/// Initializes a new instance of the <see
/// cref="VelocityCacheManagerData"/> class.
/// </summary>
public VelocityCacheManagerData()
: base("VelocityCacheManager", typeof(VelocityCacheManager))
{
RoutingClient = false;
LocalCache = false;
HostName = "localhost";
CachePort = 22233;
CacheHostName = "DistributedCacheService";
NamedCache = "default";
}
public VelocityCacheManagerData(string name, bool routingClient,
bool localCache, string hostName, int cachePort,
string cacheHostName, string namedCache)
: base(name, typeof(VelocityCacheManager))
{
RoutingClient = routingClient;
LocalCache = localCache;
HostName = hostName;
CachePort = cachePort;
CacheHostName = cacheHostName;
NamedCache = namedCache;
}
#endregion
#region Properties
[ConfigurationProperty(RoutingClientString, IsRequired = true)]
public bool RoutingClient
{
get
{
return (bool)base[RoutingClientString];
}
set
{
base[RoutingClientString] = value;
}
}
[ConfigurationProperty(LocalCacheString, IsRequired = true)]
public bool LocalCache
{
get
{
return (bool)base[LocalCacheString];
}
set
{
base[LocalCacheString] = value;
}
}
[ConfigurationProperty(HostNameString, IsRequired = true)]
public string HostName
{
get
{
return (string)base[HostNameString];
}
set
{
base[HostNameString] = value;
}
}
[ConfigurationProperty(CachePortString, IsRequired = true)]
public int CachePort
{
get
{
return (int)base[CachePortString];
}
set
{
base[CachePortString] = value;
}
}
[ConfigurationProperty(CacheHostNameString, IsRequired = true)]
public string CacheHostName
{
get
{
return (string)base[CacheHostNameString];
}
set
{
base[CacheHostNameString] = value;
}
}
[ConfigurationProperty(NamedCacheString, IsRequired = true)]
public string NamedCache
{
get
{
return (string)base[NamedCacheString];
}
set
{
base[NamedCacheString] = value;
}
}
#endregion
}
/// <summary>
/// This type supports the Enterprise Library infrastructure and is not
/// intended to be used directly from your code.
/// Represents the process to build a <see
/// cref="VelocityCacheManager"/> described by a <see
/// cref="VelocityCacheManagerData"/> configuration object.
/// </summary>
/// <remarks>This type is linked to the <see
/// cref="VelocityCacheManagerData"/> type and it is
/// used by the Custom Factory
/// to build the specific
/// <see cref="Microsoft.Practices.EnterpriseLibrary.Caching.ICacheManager"/>
/// object represented by the configuration object.
/// </remarks>
public class VelocityCacheManagerAssembler : IAssembler<ICacheManager,
CacheManagerDataBase>
{
/// <summary>
/// Builds a <see cref="VelocityCacheManager"/> based
/// on an instance of
/// <see cref="Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.
/// CustomCacheManagerData"/>.
/// </summary>
/// <param name="context">The <see cref="IBuilderContext"/>
/// that represents the current building process.</param>
/// <param name="objectConfiguration">The configuration object that
/// describes the object to build. Must be an instance of
/// <see cref="Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.
/// CustomCacheManagerData"/>.</param>
/// <param name="configurationSource">The source for configuration objects.</param>
/// <param name="reflectionCache">The cache to use retrieving
/// reflection information.</param>
/// <returns>A fully initialized instance of
/// <see cref="Microsoft.Practices.EnterpriseLibrary.Caching.ICacheManager"/>.
/// </returns>
public ICacheManager Assemble(IBuilderContext context,
CacheManagerDataBase objectConfiguration,
IConfigurationSource configurationSource,
ConfigurationReflectionCache reflectionCache)
{
VelocityCacheManagerData castObjectConfiguration =
(VelocityCacheManagerData)objectConfiguration;
VelocityCacheManager createdObject =
new VelocityCacheManager(castObjectConfiguration);
return createdObject;
}
}
}
创建 VelocityCacheManager 设计配置
拥有 VelocityCacheManager
的实现足以使用它,但您可能还希望通过 Enterprise Library 的配置工具来使用它。以下步骤将帮助您为 Enterprise Library 配置工具创建设计配置。
步骤 1
在创建的 VelocityCacheProvider.Configuration.Design
类库中,添加对以下 DLL 的引用
- Microsoft.Practices.EnterpriseLibrary.Caching
- Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.Design
- VelocityCacheProvider
第二步
右键单击 VelocityCacheProvider.Configuration.Design
并在 Application Block Software Factory 菜单中,选择 Crate Design-Time Provider Node 菜单项

在向导中,选择以下内容
- 节点名称 -
VelocityCacheManagerNode
(配置中的节点名称) - 运行时配置类型 -
CacheManagerDataBase
(节点在运行时所属的类) - 基本设计节点 -
CustomCacheManagerNode
(设计节点的基本类) - 父 UI 节点 -
CacheManagerCollectionNode
(保存我们创建的节点的节点) - 基数 -
Single
(在配置文件中仅启用VelocityCacheManager
的单个节点。如果我想拥有多个节点,则可以是Multiple
)
下图显示了所选参数

按 Finish 将创建所有相关数据和类。
步骤 3
实现创建的类。
VelocityCacheManagerNode
实现
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Drawing.Design;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design.Validation;
using Microsoft.Practices.EnterpriseLibrary.Caching.Velocity.
Configuration.Design.Properties;
using Microsoft.Practices.EnterpriseLibrary.Caching.Configuration;
namespace Microsoft.Practices.EnterpriseLibrary.Caching.Velocity.Configuration.Design
{
/// <summary>
/// Represents a <see cref="Microsoft.Practices.EnterpriseLibrary.Caching.
/// Velocity.Configuration.VelocityCacheManagerData"/> configuration element.
/// </summary>
public class VelocityCacheManagerNode : Microsoft.Practices.EnterpriseLibrary.
Caching.Configuration.Design.CustomCacheManagerNode
{
/// <summary>
/// Initialize a new instance of the <see cref="VelocityCacheManagerNode"/> class.
/// </summary>
public VelocityCacheManagerNode()
: this(new VelocityCacheManagerData(Resources.VelocityCacheManagerNodeName,
false, false, "localhost", 22233, "DistributedCacheService", "default"))
{
}
/// <summary>
/// Initialize a new instance of the <see cref="VelocityCacheManagerNode"/>
/// class with a <see cref="Microsoft.Practices.EnterpriseLibrary.Caching.
/// Velocity.Configuration.VelocityCacheManagerData"/> instance.
/// </summary>
/// <param name="data">A <see cref="Microsoft.Practices.
/// EnterpriseLibrary.Caching.Velocity.Configuration.VelocityCacheManagerData"/>
/// instance</param>
public VelocityCacheManagerNode(VelocityCacheManagerData data)
{
if (null == data)
{
throw new ArgumentNullException("error in creating the data node -
VelocityCacheManagerData is null");
}
Rename(data.Name);
this.routingClient = data.RoutingClient;
this.localCache = data.LocalCache;
this.hostName = data.HostName;
this.cachePort = data.CachePort;
this.cacheHostName = data.CacheHostName;
this.namedCache = data.NamedCache;
Type = typeof(VelocityCacheManager).ToString();
}
/// <summary>
/// Gets the <see cref="Microsoft.Practices.EnterpriseLibrary.Caching.
/// Velocity.Configuration.VelocityCacheManagerData"/> this node represents.
/// </summary>
/// <value>
/// The <see cref="Microsoft.Practices.EnterpriseLibrary.Caching.
/// Velocity.Configuration.VelocityCacheManagerData"/> this node represents.
/// </value>
[Browsable(false)]
public override CacheManagerDataBase CacheManagerData
{
get
{
VelocityCacheManagerData data = new VelocityCacheManagerData();
data.Name = this.Name;
data.RoutingClient = this.routingClient;
data.LocalCache = this.localCache;
data.HostName = this.hostName;
data.CachePort = this.cachePort;
data.CacheHostName = this.cacheHostName;
data.NamedCache = this.namedCache;
return data;
}
}
/// <summary>
/// Releases the unmanaged resources used by the
/// <see cref="VelocityCacheManagerNode"/> and optionally releases
/// the managed resources.
/// </summary>
/// <param name="disposing">
/// <see langword="true"/> to release both managed and unmanaged resources;
/// <see langword="false"/> to release only unmanaged resources.
/// </param>
protected override void Dispose(bool disposing)
{
if (disposing)
{
}
base.Dispose(disposing);
}
private System.Boolean routingClient;
/// <summary>
///
/// </summary>
/// <value>
///
/// </value>
[SRDescription("RoutingClientDescription", typeof(Resources))]
[SRCategory("CategoryGeneral", typeof(Resources))]
public System.Boolean RoutingClient
{
get { return this.routingClient; }
set { this.routingClient = value; }
}
private System.Boolean localCache;
/// <summary>
///
/// </summary>
/// <value>
///
/// </value>
[SRDescription("LocalCacheDescription", typeof(Resources))]
[SRCategory("CategoryGeneral", typeof(Resources))]
public System.Boolean LocalCache
{
get { return this.localCache; }
set { this.localCache = value; }
}
private System.String hostName;
/// <summary>
///
/// </summary>
/// <value>
///
/// </value>
[SRDescription("HostNameDescription", typeof(Resources))]
[SRCategory("CategoryGeneral", typeof(Resources))]
public System.String HostName
{
get { return this.hostName; }
set { this.hostName = value; }
}
private System.Int32 cachePort;
/// <summary>
///
/// </summary>
/// <value>
///
/// </value>
[SRDescription("CachePortDescription", typeof(Resources))]
[SRCategory("CategoryGeneral", typeof(Resources))]
public System.Int32 CachePort
{
get { return this.cachePort; }
set { this.cachePort = value; }
}
private System.String cacheHostName;
/// <summary>
///
/// </summary>
/// <value>
///
/// </value>
[SRDescription("CacheHostNameDescription", typeof(Resources))]
[SRCategory("CategoryGeneral", typeof(Resources))]
public System.String CacheHostName
{
get { return this.cacheHostName; }
set { this.cacheHostName = value; }
}
private System.String namedCache;
/// <summary>
///
/// </summary>
/// <value>
///
/// </value>
[SRDescription("NamedCacheDescription", typeof(Resources))]
[SRCategory("CategoryGeneral", typeof(Resources))]
public System.String NamedCache
{
get { return this.namedCache; }
set { this.namedCache = value; }
}
}
}
NodeMapRegistrar
实现
//===============================================================================
// Microsoft patterns & practices Enterprise Library
// Application Block Software Factory
//===============================================================================
// Copyright © Microsoft Corporation. All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design;
using Microsoft.Practices.EnterpriseLibrary.Caching.Velocity.Configuration.
Design.Properties;
namespace Microsoft.Practices.EnterpriseLibrary.Caching.Velocity.Configuration.Design
{
sealed class NodeMapRegistrar : Microsoft.Practices.EnterpriseLibrary.
Configuration.Design.NodeMapRegistrar
{
public NodeMapRegistrar(IServiceProvider serviceProvider)
: base(serviceProvider)
{
}
public override void Register()
{
AddSingleNodeMap(Resources.VelocityCacheManagerNodeUICommandText,
typeof(VelocityCacheManagerNode),
typeof(VelocityCacheManagerData));
}
}
}
CommandRegistrar
实现
//===============================================================================
// Microsoft patterns & practices Enterprise Library
// Application Block Software Factory
//===============================================================================
// Copyright © Microsoft Corporation. All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design;
using Microsoft.Practices.EnterpriseLibrary.Caching.Velocity.Configuration.
Design.Properties;
namespace Microsoft.Practices.EnterpriseLibrary.Caching.Velocity.Configuration.Design
{
sealed partial class CommandRegistrar : Microsoft.Practices.
EnterpriseLibrary.Configuration.Design.CommandRegistrar
{
public CommandRegistrar(IServiceProvider serviceProvider)
: base(serviceProvider)
{
}
public override void Register()
{
AddVelocityCacheManagerNodeCommand();
AddDefaultCommands(typeof(VelocityCacheManagerNode));
}
}
}
CommandRegistrar.VelocityCacheManagerNode
实现
using System; using Microsoft.Practices.EnterpriseLibrary.Caching.Velocity. Configuration.Design.Properties; using Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.Design; namespace Microsoft.Practices.EnterpriseLibrary.Caching.Velocity.Configuration.Design { sealed partial class CommandRegistrar { private void AddVelocityCacheManagerNodeCommand() { AddSingleChildNodeCommand( Resources.VelocityCacheManagerNodeUICommandText, Resources.VelocityCacheManagerNodeUICommandLongText, typeof(VelocityCacheManagerNode), typeof(CacheManagerCollectionNode)); } } }
步骤 4
编辑 Resources 文件,使其看起来像

就是这样。
现在,您只需要将生成的两个 DLL 拖放到配置工具的目录中,就可以使用该工具来配置 VelocityCacheManager
。下图显示了它在 Enterprise Library 的配置工具中的外观

摘要
本文介绍了如何为 Enterprise Library 的 Caching Application Block 创建一个简单的 Velocity 缓存管理器。 我还介绍了如何将创建的提供程序库集成到 Enterprise Library 的配置工具中。 您可以从这里下载提供程序库。
您可以使用我编写的提供程序,并在您的实现中更改我提供的代码。