 /*
 * Copyright 2003-2005 The Apache Software Foundation
 *
 * 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.
 */

namespace Agility.Core
{
	/// <summary>
	/// A {@link Command} encapsulates a unit of processing work to be
	/// performed, whose purpose is to examine and/or modify the state of a
	/// transaction that is represented by a {@link Context}. 
	/// </summary>
	/// <remarks>
	/// <p>Individual {@link Command}s can be assembled into a {@link Chain}, which allows
	/// them to either complete the required processing or delegate further
	/// processing to the next {@link Command} in the {@link Chain}.</p>
	///
	/// <p>{@link Command} implementations should be designed in a thread-safe
	/// manner, suitable for inclusion in multiple {@link Chain}s that might be
	/// processed by different threads simultaneously.  In general, this implies
	/// that {@link Command} classes should not maintain state information in
	/// instance variables.  Instead, state information should be maintained via
	/// suitable modifications to the attributes of the {@link Context} that is
	/// passed to the <code>Execute</code> command.</p>
	///
	/// <p>{@link Command} implementations typically retrieve and store state
	/// information in the {@link Context} instance that is passed as a parameter
	/// to the <code>Execute</code> method, using particular keys into the
	/// <code>IDictionary</code> that can be acquired via 
	/// <code>Context.Keys</code>. 
	/// 
	/// <p>To improve interoperability of
	/// {@link Command} implementations, a useful design pattern is to expose the
	/// key values used as Properties of the {@link Command}
	/// implementation class itself.  For example, a {@link Command} that requires
	/// an input and an output key might implement the following properties:</p>
	///
	/// <pre>
	///   private string _InputKey = "input";
	///   public string InputKey {
	///    get { return _InputKey; }
	///	   set { _InputKey = value; }
	///   }
	///
	///   private string _OutputKey = "output";
	///   public string OutputKey {
	///    get { return _OutputKey; }
	///	   set { _OutputKey = value; }
	///   }
	/// </pre>
	///
	/// <p>And the operation of accessing the "input" information in the context
	/// would be executed by calling:</p>
	///
	/// <pre>
	///   string input = context[getInputKey()] as string;
	/// </pre>
	///
	/// <p>instead of hard coding the key attribute.  The use of the "Key"
	/// suffix on such property names is a useful convention to identify properties
	/// being used in this fashion, as opposed to properties that simply
	/// configure the internal operation of this {@link Command}.</p>
	/// </remarks>
	public interface ICommand
	{
		/// <summary>
		/// Execute a unit of processing work to be performed.  
		/// </summary>
		/// <remarks>
		/// This {@link ICommand} may either complete the required processing
		/// and return <code>true</code>, or delegate remaining processing
		/// to the next {@link ICommand} in a {@link IChain} containing this
		/// {@link ICommand} by returning <code>false</code>
		/// </remarks>
		/// <param name="context">The {@link IContext} to be processed by this
		///  {@link ICommand}</param>
		/// <returns>
		/// <code>true</code> if the processing of this {@link Context}
		///  has been completed, or <code>false</code> if the processing
		///  of this {@link IContext} should be delegated to a subsequent
		///  {@link ICommand} in an enclosing {@link IChain}
		/// </returns>
		bool Execute(IContext context);

	}
}