//----------------------------------------------------------------------- // // 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; } } }