在.NET Framework中,经常需要为应用程序配置特定的设置。标准的配置节可能无法满足所有需求,因此.NET Framework提供了丰富的接口来创建自定义配置节。本文是关于WCF Router在企业WCTP服务中的一系列文章的第二部分,将展示如何创建一个自定义配置节来存储Router将发送信息到的所有服务的设置。
在本节中,将展示如何创建一个自定义配置节,用于存储Router将发送信息到的所有服务的设置。
希望在XML配置中有一个如下所示的节:
这是通过使用三个从System.Configuration命名空间派生的自定义类来实现的。这些类是:
WctpConfig类是从ConfigurationSection派生的,代表自定义配置的根XML元素。由于它只包含一个集合,代码相当简单:
[ConfigurationProperty("receivers", IsDefaultCollection = false)]
[ConfigurationCollection(typeof(ReceiverCollection), AddItemName = "addReceiver",
ClearItemsName = "clearReceivers", RemoveItemName = "removeReceiver")]
public ReceiverCollection Receivers
{
get
{
return (ReceiverCollection)(base["receivers"]);
}
}
拥有
ReceiverCollection类是从ConfigurationElementCollection派生的。它包含通过整型索引或字符串键获取集合中元素的方法,以及添加、移除和清除子元素的方法。这个类相当通用,稍作修改就可以在其他项目中使用。
这是从ConfigurationElement派生的类。它包含了配置树的真正自定义代码。让看看这个类将为做什么。
在这个类中,将拥有决定将WCTP消息路由到哪个可能的Receiver所需的信息。所以希望它有一些非常特定的信息:
实现这些相当简单。这里有一个HandlesText属性的示例。
///
///
Whether or not the service supports text messages. True by default.
///
///
[ConfigurationProperty("text", IsRequired = false, DefaultValue = true)]
public bool HandlesText
{
get
{
return (bool)this["text"];
}
set
{
this["text"] = value;
}
}
提前一点到WCTP HTTP应用程序的实现,使用配置非常简单。在决定将特定消息路由到哪个WCF服务时,可以执行一个简单的LINQ查询来返回一个按优先级排序的潜在服务列表。
//
Create a LINQ query to get the order of services to send the message to
WctpConfig config = (WctpConfig)(ConfigurationManager.GetSection("WCTP"));
IEnumerable receivers;
if (payload.GetType() == typeof(string))
{
receivers = config.Receivers.OfType()
.Where(s => s.HandlesText)
.Where(s => Regex.Match(originator.senderID, s.SenderFilter).Success)
.Where(s => Regex.Match(recipient.recipientID, s.RecipientFilter).Success)
.OrderByDescending(s => s.Priority)
.ThenByDescending(s => s.ExclusiveHandler)
.ThenByDescending(s => s.OneWay);
}
else
{
receivers = config.Receivers.OfType()
.Where(s => s.HandlesBinary)
.Where(s => Regex.Match(originator.senderID, s.SenderFilter).Success)
.Where(s => Regex.Match(recipient.recipientID, s.RecipientFilter).Success)
.OrderByDescending(s => s.Priority)
.ThenByDescending(s => s.ExclusiveHandler)
.ThenByDescending(s => s.OneWay);
}
Isn't that nice!