#region License
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#endregion
using System;
using System.Messaging;
using Spring.Objects.Factory;
using Spring.Objects.Factory.Config;
namespace Spring.Messaging.Support{
/// <summary>
/// Factory for creating MessageQueues. This factory will create prototype instances, i.e. every call to GetObject
/// will return a new MessageQueue object.
/// </summary>
/// <remarks>All MessageQueue constructor arguments are exposed as properties of the factory object. As this
/// is a <see cref="IConfigurableFactoryObject"/> use the PropertyTemplate property to specify additional
/// configuration of the MessageQueue.
/// </remarks>
/// <author>Mark Pollack</author>
public class MessageQueueFactoryObject : IConfigurableFactoryObject, IObjectNameAware
{
// fields used in constructor
private string path = string.Empty;
private bool modeDenySharedReceive;
private bool enableCache;
private QueueAccessMode accessMode = QueueAccessMode.SendAndReceive;
// To avoid stale handles when MSMQ restarts and when stopping async recieve/peek operations
private bool enableConnectionCache = false;
private IObjectDefinition productTemplate;
private bool messageReadPropertyFilterSetAll = true;
private bool messageReadPropertyFilterSetDefaults = false;
private MessageQueueCreatorDelegate messageCreatorDelegate;
private bool remoteQueue = false;
private bool remoteQueueIsTransactional = false;
private string objectName;
/// <summary>
/// Gets or sets an instance of the MessageQueueCreator delegate that will be used to create the
/// MessageQueue object, instead of using the various public properties on this class such
/// as Path, AccessMode, etc. Not intended for end-users but rather as a means to help
/// register MessageQueueFactoryObject at runtime using convenience method on the IMessageQueueFactory.
/// </summary>
/// <remarks>
/// Can also be specifed using an instance of MessageCreatorDelegate. If both are specifed, the
/// Interface implementation has priority.
/// </remarks>
/// <value>The function that is responsbile for creating a message queue.</value>
public MessageQueueCreatorDelegate MessageCreatorDelegate
{
get { return messageCreatorDelegate; }
set { messageCreatorDelegate = value; }
}
/// <summary>
/// Gets or sets the path used to create a MessageQueue instance.
/// </summary>
/// <value>The location of the queue.</value>
public string Path
{
get { return path; }
set { path = value; }
}
/// <summary>
/// Gets or sets a value indicating whether to create the MessageQueue instance with
/// exclusive read access to the first application that accesses the queue
/// </summary>
/// <value>
/// <c>true</c> to grant exclusive read access to the first application that accesses the queue; otherwise, <c>false</c>.
/// </value>
public bool DenySharedReceive
{
get { return modeDenySharedReceive; }
set { modeDenySharedReceive = value; }
}
/// <summary>
/// Gets or sets the queue access mode.
/// </summary>
/// <value>The queue access mode.</value>
/// <see cref="AccessMode"/>
public QueueAccessMode AccessMode
{
get { return accessMode; }
set { accessMode = value; }
}
/// <summary>
/// Gets or sets a value indicating whether [enable cache].
/// </summary>
/// <value><c>true</c> to create and use a connection cache; otherwise <c>false</c>.</value>
public bool EnableCache
{
get { return enableCache; }
set { enableCache = value; }
}
/// <summary>
/// Sets a value indicating whether to enable connection cache. The default is false, which
/// is different than the default value when creating a System.Messaging.MessageQueue object.
/// </summary>
/// <value>
/// <c>true</c> if enable connection cache; otherwise, <c>false</c>.
/// </value>
public bool EnableConnectionCache
{
set { enableConnectionCache = value; }
}
/// <summary>
/// Sets a value indicating whether to retrieve all message properties when receiving a message.
/// </summary>
/// <value>
/// <c>true</c> if should etrieve all message properties when receiving a message; otherwise, <c>false</c>.
/// </value>
public bool MessageReadPropertyFilterSetAll
{
set { messageReadPropertyFilterSetAll = value; }
}
/// <summary>
/// Sets a value indicating whether to set the filter values of common Message Queuing properties
/// to true and the integer-valued properties to their default values..
/// </summary>
/// <value>
/// <c>true</c> if should set the filter values of common Message Queuing properties; otherwise, <c>false</c>.
/// </value>
public bool MessageReadPropertyFilterSetDefaults
{
set { messageReadPropertyFilterSetDefaults = value; }
}
/// <summary>
/// Gets or sets a value indicating whether the queue is a remote queue.
/// </summary>
/// <remarks>
/// The operations that one can perform on the MessageQueue depend on if it is local or remote, for
/// example checking if it is transactional. This is very difficult to determine programmatically.
/// The property was made virtual so it can be overridden to take into account custom heuristics you
/// may want to use to determine this programmatically.
/// </remarks>
/// <value><c>true</c> if remote queue; otherwise, <c>false</c>.</value>
public virtual bool RemoteQueue
{
get { return remoteQueue; }
set { remoteQueue = value; }
}
/// <summary>
/// Gets or sets a value indicating whether the remote queue is transactional.
/// </summary>
/// <value>
/// <c>true</c> if the remote queue is transactional; otherwise, <c>false</c>.
/// </value>
public virtual bool RemoteQueueIsTransactional
{
get { return remoteQueueIsTransactional; }
set { remoteQueueIsTransactional = value; }
}
#region IFactoryObject Members
/// <summary>
/// Retrun a configured MessageQueue object.
/// </summary>
/// <returns>A newly configured MessageQueue object</returns>
public object GetObject()
{
if (MessageCreatorDelegate != null)
{
return MessageCreatorDelegate();
}
else
{
MessageQueue mq = new MessageQueue(Path, DenySharedReceive, EnableCache, AccessMode);
if (messageReadPropertyFilterSetDefaults)
{
mq.MessageReadPropertyFilter.SetDefaults();
}
if (messageReadPropertyFilterSetAll)
{
mq.MessageReadPropertyFilter.SetAll();
}
return mq;
}
}
/// <summary>
/// Return the <see cref="System.Type"/> of object that this
/// <see cref="Spring.Objects.Factory.IFactoryObject"/> creates, or
/// <see langword="null"/> if not known in advance.
/// </summary>
/// <value>The type System.Messaging.MessageQueue</value>
public Type ObjectType
{
get { return typeof (MessageQueue); }
}
/// <summary>
/// Is the object managed by this factory a singleton or a prototype?
/// </summary>
/// <value>return false, a new object will be created for each request of the object</value>
public bool IsSingleton
{
get { return false; }
}
#region IConfigurableFactoryObject Members
/// <summary>
/// Gets the template object definition that should be used
/// to configure the instance of the object managed by this factory.
/// </summary>
/// <value>The object definition to configure the factory's product</value>
public IObjectDefinition ProductTemplate
{
get { return productTemplate; }
set { productTemplate = value; }
}
#endregion
#endregion
/// <summary>
/// Set the name of the object in the object factory that created this object.
/// </summary>
/// <value>The name of the object in the factory.</value>
/// <remarks>
/// <p>
/// Invoked after population of normal object properties but before an init
/// callback like <see cref="Spring.Objects.Factory.IInitializingObject"/>'s
/// <see cref="Spring.Objects.Factory.IInitializingObject.AfterPropertiesSet"/>
/// method or a custom init-method.
/// </p>
/// </remarks>
public string ObjectName
{
set { objectName = value; }
get { return ObjectName; }
}
}
}
|