最近一直在看Artech大仙的WCF系列的文章,因为其中涉及很多PIAB的内容,所以我也开始看Artech大仙PIAB相关的文章。
但是今天看Artech的Enterprise Library Policy Injection Application Block 之三时遇到了一些问题。
唉。。。其实说来说来惭愧。这篇文章是很老了,我今天才来看。。。
我使用的EnterpriseLibrary版本是4.1。
代码几乎是照搬文章上的代码。因为版本变更的缘故,所以原有代码中的一些接口已经改变。但是总体思路是没有变化的。
稍作修改就完成原文上使用Attribute方式实现PolicyInjection的代码。
但是在使用Configuration方式时出现了意外的问题。
我用配置工具生成配置文件时,死活都无法添加Hanler。每次都在选择了dll文件后,提示:找不到实现了ICallHanler的类型。但是分明是已经存实现了ICallHanler的OrderValidationCallHandler。
然后我尝试手动将handler写入配置文件。在程序运行到PolicyInjection.Create<OrderProcessor>();这段又会报"未实现该方法或操作"的异常。。。
后来我是这样解决这个问题的
1.将[ConfigurationElementType(typeof(OrderValidationCallHandlerData))]
改成 [ConfigurationElementType(typeof(CustomCallHandlerData))]
2.为OrderValidationCallHandler添加一个包含NameValueCollection参数的构造函数。通过此构造函数的NameValueCollection参数获取配置节点的属性和对应值,并初始化OrderValidationCallHandler.ValidateTotalPrice、OrderValidationCallHandler.ValidateSupplier和OrderValidationCallHandler.Order。
其实这一步做修改的代码实现的就是原来OrderValidationCallHandlerAssembler类的功能--初始化OrderValidationCallHandler。
框架通过这个特殊的构造函数将配置中的属性以NameValueCollection的形式传到CustomCallHandler,然后CustomCallHandler通过获得配置初始化类。
经过这两部的修改Configuration方式实现PolicyInjection的问题就搞定了。此时再使用配置工具添加Handler不会再报错了。
大概的看了一下CustomCallHandlerData,它继承了CallHandlerData, IHelperAssistedCustomConfigurationData<CustomCallHandlerData>, ICustomProviderData
之所以原来的代码会出现"未实现该方法或操作"的异常,估计是因为没有继承IHelperAssistedCustomConfigurationData<CustomCallHandlerData>和ICustomProviderData所致。
具体的细节我也没有太深入,等有时间再看吧。
半夜三更了,先把结果挂上。
[ConfigurationElementType(typeof(CustomCallHandlerData))]
public class OrderValidationCallHandler : ICallHandler
{
public OrderValidationCallHandler()
{
}
public OrderValidationCallHandler(NameValueCollection parameterValues)
{
if (parameterValues["validateSupplier"] != null)
{
this.ValidateSupplier = Convert.ToBoolean(parameterValues["validateSupplier"]);
}
if (parameterValues["validateTotalPrice"] != null)
{
this.ValidateTotalPrice = Convert.ToBoolean(parameterValues["validateTotalPrice"]);
}
if (parameterValues["order"] != null)
{
this.Order = Convert.ToInt32(parameterValues["order"]);
}
}
private static IList<string> _legalSuppliers;
public static IList<string> LegalSuppliers
{
get
{
if (_legalSuppliers == null)
{
_legalSuppliers = new List<string>();
_legalSuppliers.Add("Company AAA");
_legalSuppliers.Add("Company BBB");
_legalSuppliers.Add("Company CCC");
}
return _legalSuppliers;
}
}
#region Public Properties
public bool ValidateTotalPrice
{ get; set; }
public bool ValidateSupplier
{ get; set; }
#endregion
#region ICallHandler Members
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
if (input.Inputs.Count == 0)
{
return getNext()(input, getNext);
}
Order order = input.Inputs[0] as Order;
if (order == null)
{
return getNext()(input, getNext);
}
if (order.OrderDate > DateTime.Today)
{
return input.CreateExceptionMethodReturn(
new OrderValidationException("The order date is later than the current date!~"));
}
if (order.Items.Count == 0)
{
return input.CreateExceptionMethodReturn(
new OrderValidationException("There are not any items for the order!~"));
}
if (this.ValidateSupplier)
{
if (!LegalSuppliers.Contains<string>(order.Supplier))
{
return input.CreateExceptionMethodReturn(
new OrderValidationException("The supplier is inllegal!~"));
}
}
if (this.ValidateTotalPrice)
{
double totalPrice = 0;
foreach (OrderItem item in order.Items)
{
totalPrice += item.Quantity * item.UnitPrice;
}
if (totalPrice != order.TotalPrice)
{
return input.CreateExceptionMethodReturn(new OrderValidationException("The sum of the order item is not equal to the order total price!"));
}
}
return getNext()(input, getNext);
}
public int Order
{ get; set; }
#endregion
}