Aja*_*axx 8 binary wcf encoding net-tcp
我有一个没有互操作性要求的自定义Intranet应用程序.我们以双工模式编程构造NetTcp通道以传递消息.我们想要更改消息编码,但无法弄清楚如何实现这一点.
我们采取的方法(失败)是将NetTcpBinding扩展为一个名为LeanTcpBinding的新类,如下所示:
internal class LeanTcpBinding : NetTcpBinding
{
private static readonly ILog _log =
LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public override BindingElementCollection CreateBindingElements()
{
BindingElementCollection bindingElementCollection = base.CreateBindingElements();
BindingElement encodingElement = bindingElementCollection.FirstOrDefault(
bindingElement => bindingElement is BinaryMessageEncodingBindingElement);
if (encodingElement != null)
{
int index = bindingElementCollection.IndexOf(encodingElement);
bindingElementCollection.RemoveAt(index);
bindingElementCollection.Insert(index, new LeanBinaryMessageEncodingBindingElement());
}
else
{
_log.Warn("Encoding not found");
}
return bindingElementCollection;
}
}
Run Code Online (Sandbox Code Playgroud)
显然,我们正在尝试用我们自己的替换默认的BinaryMessageEncodingBindingElement.只是为了开始使用,LeanBinaryMessageEncodingBindingElement是BinaryMessageEncodingBindingElement的扩展,如下所示:
internal class LeanBinaryMessageEncodingBindingElement : MessageEncodingBindingElement
{
private readonly BinaryMessageEncodingBindingElement _bindingElement;
///
/// Initializes a new instance of the class.
///
public LeanBinaryMessageEncodingBindingElement()
{
_bindingElement = new BinaryMessageEncodingBindingElement();
}
///
/// Initializes a new instance of the class.
///
/// The binding element.
public LeanBinaryMessageEncodingBindingElement(BinaryMessageEncodingBindingElement bindingElement)
{
_bindingElement = bindingElement;
}
///
/// Initializes a new instance of the class.
///
/// The element to be cloned.
/// The binding element.
public LeanBinaryMessageEncodingBindingElement(MessageEncodingBindingElement elementToBeCloned, BinaryMessageEncodingBindingElement bindingElement)
: base(elementToBeCloned)
{
_bindingElement = bindingElement;
}
///
/// When overridden in a derived class, returns a copy of the binding element object.
///
///
/// A object that is a deep clone of the original.
///
public override BindingElement Clone()
{
return new LeanBinaryMessageEncodingBindingElement(
(BinaryMessageEncodingBindingElement)_bindingElement.Clone());
}
///
/// When overridden in a derived class, creates a factory for producing message encoders.
///
///
/// The used to produce message encoders.
///
public override MessageEncoderFactory CreateMessageEncoderFactory()
{
return new LeanBinaryMessageEncoderFactory(_bindingElement.CreateMessageEncoderFactory());
}
///
/// When overridden in a derived class, gets or sets the message version that can be handled by the message encoders produced by the message encoder factory.
///
///
/// The used by the encoders produced by the message encoder factory.
///
public override MessageVersion MessageVersion
{
get { return _bindingElement.MessageVersion; }
set { _bindingElement.MessageVersion = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试使用绑定时,它完全按照我认为它应该做的...它取代了BinaryMessageEncodingBindingElement.但是,即使通过通道交换消息,我也永远不会调用LeanBinaryMessageEncodingBindingElement.CreateMessageEncoderFactory().
任何人对如何正确地做这个有任何建议?
Kenny Wolf澄清了遗漏的内容,并在下面的博客文章中记录了这些内容.
对于不耐烦的问题是,默认情况下,MessageEncoderBindingElement不会将自身添加到上下文的绑定参数中.因此,当稍后传输找到MessageEncoderBindingElement时,它找不到我(或您)创建的那个并且具有我在原始帖子中记录的静默失败.
不幸的是,您必须按如下方式覆盖所有CanBuildXXX和BuildXXX方法,以确保将绑定元素添加到上下文的绑定参数中.
public override bool CanBuildChannelFactory(BindingContext context)
{
if (context == null) {
throw new ArgumentNullException("context");
}
context.BindingParameters.Add(this);
return context.CanBuildInnerChannelFactory();
}
public override bool CanBuildChannelListener(BindingContext context)
{
if (context == null) {
throw new ArgumentNullException("context");
}
context.BindingParameters.Add(this);
return context.CanBuildInnerChannelListener();
}
public override IChannelFactory BuildChannelFactory(BindingContext context)
{
if (context == null) {
throw new ArgumentNullException("context");
}
context.BindingParameters.Add(this);
return context.BuildInnerChannelFactory();
}
public override IChannelListener BuildChannelListener(BindingContext context)
{
if (context == null) {
throw new ArgumentNullException("context");
}
context.BindingParameters.Add(this);
return context.BuildInnerChannelListener();
}