这是一个抽象类,包含了两个protected字段,其中m_bindingConstraint即形成职责链的关键,通过AddConstraint()方法可以将BindingConstraint对象加入到职责链中,而字段m_hasNextConstraint则用来标识当前对象之下是否还存在BindingConstraint对象。抽象方法Constraint()则实现约束性检查的业务逻辑,同时还包括对职责链是否存在下一个职责对象的判断。例如BasicHttpBindingConstraint的定义如下:
public class BasicHttpBindingConstraint:BindingConstraint根据传入的endpoint对象,判断绑定的名称是否为"BasicHttpBinding",如果是,则执行该约束对象的约束性检查,如果不是,则去寻找职责链中的其它对象(根据m_hasNextConstraint判断)。正是通过这样的实现方式,当客户端调用BindingConstraint的Constraint()方法时,就可以根据传入的ServiceEndpoint对象,智能地找到符合自己条件的BindingConstraint对象,并执行Constraint()方法进行约束性检查。
{
public override bool Constraint(ServiceEndpoint endpoint)
{
if (endpoint.Binding.Name == "BasicHttpBinding")
{
//check binding and address's scheme
if (endpoint.Address.Scheme.ToLower() != "http"
&& endpoint.Address.Scheme.ToLower() != "https")
{
throw new BindingConstraintException(
"the binding is mismatch with address schema.");
}
//check BasicHttpBinding Constraint;
return true;
}
else
{
if (m_hasNextConstraint)
{
return m_bindingConstraint.Constraint(endpoint);
}
else
{
return false;
}
}
}
}
在我的《软件设计精要与模式》一书中,在应用职责链模式时,我的建议是最好提供专门创建职责链的工厂类,在本例中自然也不例外:
public class BindingConstraintFactory
{
public static BindingConstraint CreateConstraint()
{
BindingConstraint basicHttp = new BasicHttpBindingConstraint();
BindingConstraint netTcp = new NetTcpBindingConstraint();
BindingConstraint netPeerTcp = new NetPeerTcpBindingConstraint();
BindingConstraint netNamedPipe = new NetNamedPipeBindingConstraint();
BindingConstraint wsHttp = new WSHttpBindingConstraint();
BindingConstraint wsFederationHttp = new WSFederationHttpBindingConstraint();
BindingConstraint wsDualHttp = new WSDualHttpBindingConstraint();
BindingConstraint netMsmq = new NetMsmqBindingConstraint();
BindingConstraint msmqIntegration = new MsmqIntegrationBindingConstraint();
netMsmq.AddConstraint(msmqIntegration);
wsDualHttp.AddConstraint(netMsmq);
wsFederationHttp.AddConstraint(wsDualHttp);
wsHttp.AddConstraint(wsFederationHttp);
netNamedPipe.AddConstraint(wsHttp);
netPeerTcp.AddConstraint(netNamedPipe);
netTcp.AddConstraint(netPeerTcp);
basicHttp.AddConstraint(netTcp);
return basicHttp;
}
}