//-----------------------------------------------------------------------
//
// Copyright (c) Outercurve Foundation. All rights reserved.
//
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.Messaging {
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Reflection;
using Validation;
///
/// A channel that uses the standard message factory.
///
public abstract class StandardMessageFactoryChannel : Channel {
///
/// The message types receivable by this channel.
///
private readonly ICollection messageTypes;
///
/// The protocol versions supported by this channel.
///
private readonly ICollection versions;
///
/// Initializes a new instance of the class.
///
/// The message types that might be encountered.
/// All the possible message versions that might be encountered.
/// The host factories.
/// The binding elements to use in sending and receiving messages.
/// The order they are provided is used for outgoing messgaes, and reversed for incoming messages.
protected StandardMessageFactoryChannel(ICollection messageTypes, ICollection versions, IHostFactories hostFactories, IChannelBindingElement[] bindingElements = null)
: base(new StandardMessageFactory(), bindingElements ?? new IChannelBindingElement[0], hostFactories) {
Requires.NotNull(messageTypes, "messageTypes");
Requires.NotNull(versions, "versions");
this.messageTypes = messageTypes;
this.versions = versions;
this.StandardMessageFactory.AddMessageTypes(GetMessageDescriptions(this.messageTypes, this.versions, this.MessageDescriptions));
}
///
/// Gets or sets a tool that can figure out what kind of message is being received
/// so it can be deserialized.
///
internal StandardMessageFactory StandardMessageFactory {
get { return (Messaging.StandardMessageFactory)this.MessageFactory; }
set { this.MessageFactory = value; }
}
///
/// Gets or sets the message descriptions.
///
internal sealed override MessageDescriptionCollection MessageDescriptions {
get {
return base.MessageDescriptions;
}
set {
base.MessageDescriptions = value;
// We must reinitialize the message factory so it can use the new message descriptions.
var factory = new StandardMessageFactory();
factory.AddMessageTypes(GetMessageDescriptions(this.messageTypes, this.versions, value));
this.MessageFactory = factory;
}
}
///
/// Gets or sets a tool that can figure out what kind of message is being received
/// so it can be deserialized.
///
protected sealed override IMessageFactory MessageFactory {
get {
return (StandardMessageFactory)base.MessageFactory;
}
set {
StandardMessageFactory newValue = (StandardMessageFactory)value;
base.MessageFactory = newValue;
}
}
///
/// Generates all the message descriptions for a given set of message types and versions.
///
/// The message types.
/// The message versions.
/// The cache to use when obtaining the message descriptions.
/// The generated/retrieved message descriptions.
private static IEnumerable GetMessageDescriptions(ICollection messageTypes, ICollection versions, MessageDescriptionCollection descriptionsCache)
{
Requires.NotNull(messageTypes, "messageTypes");
Requires.NotNull(descriptionsCache, "descriptionsCache");
// Get all the MessageDescription objects through the standard cache,
// so that perhaps it will be a quick lookup, or at least it will be
// stored there for a quick lookup later.
var messageDescriptions = new List(messageTypes.Count * versions.Count);
messageDescriptions.AddRange(from version in versions
from messageType in messageTypes
select descriptionsCache.Get(messageType, version));
return messageDescriptions;
}
}
}