#region License
/*
* Copyright 2002-2005 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
#region Imports
using System;
using System.Globalization;
using Common.Logging;
using Spring.Objects.Factory;
using Spring.Objects.Factory.Support;
using Spring.Util;
#endregion
namespace Spring.Aop.Target{
/// <summary>
/// Base class for dynamic <see cref="Spring.Aop.ITargetSource"/>
/// implementations that can create new prototype object instances to
/// support a pooling or new-instance-per-invocation strategy.
/// </summary>
/// <remarks>
/// <p>
/// All such <see cref="Spring.Aop.ITargetSource"/>s must run in an
/// <see cref="Spring.Objects.Factory.IObjectFactory"/>, as they need to
/// call the <see cref="Spring.Objects.Factory.IObjectFactory.GetObject(string)"/>
/// method to create a new prototype instance.
/// </p>
/// </remarks>
/// <author>Rod Johnson</author>
/// <author>Federico Spinazzi (.NET)</author>
public abstract class AbstractPrototypeTargetSource
: ITargetSource, IObjectFactoryAware, IInitializingObject
{
#region Constructor (s) / Destructor
/// <summary>
/// Creates a new instance of the
/// <see cref="Spring.Aop.Target.AbstractPrototypeTargetSource"/>
/// class.
/// </summary>
/// <remarks>
/// <p>
/// This is an <see langword="abstract"/> class, and as such exposes no
/// public constructors.
/// </p>
/// </remarks>
protected AbstractPrototypeTargetSource()
{
}
#endregion
#region Properties
/// <summary>
/// The name of the target object to be created on each invocation.
/// </summary>
/// <remarks>
/// <p>
/// This object should be a prototype, or the same instance will always
/// be obtained from the owning <see cref="ObjectFactory"/>.
/// </p>
/// </remarks>
public virtual string TargetObjectName
{
get { return _targetObjectName; }
set {
_targetObjectName = value;
}
}
/// <summary>
/// The <see cref="System.Type"/> of the target object.
/// </summary>
public virtual Type TargetType
{
get { return _targetType; }
}
/// <summary>
/// Is the target source static?
/// </summary>
/// <value>
/// <see langword="true"/> if the target source is static.
/// </value>
public virtual bool IsStatic
{
get { return false; }
}
/// <summary>
/// The target factory that will be used to perform the lookup
/// of the object referred to by the <see cref="TargetObjectName"/>
/// property.
/// </summary>
/// <remarks>
/// <p>
/// Needed so that prototype instances can be created as necessary.
/// </p>
/// </remarks>
/// <value>
/// The owning <see cref="Spring.Objects.Factory.IObjectFactory"/>
/// (will never be <see langword="null"/>).
/// </value>
/// <exception cref="Spring.Objects.ObjectsException">
/// In case of initialization errors.
/// </exception>
/// <seealso cref="Spring.Objects.Factory.IObjectFactoryAware.ObjectFactory"/>
public virtual IObjectFactory ObjectFactory
{
get { return _owningObjectFactory; }
set
{
_owningObjectFactory = value;
if (!value.IsPrototype(TargetObjectName))
{
throw new ObjectDefinitionStoreException(
"Cannot use PrototypeTargetSource against a " +
"Singleton object; instances would not be independent.");
}
#region Instrumentation
if (logger.IsDebugEnabled)
{
logger.Debug(string.Format(
"Getting object with name '{0}' to determine class.",
TargetObjectName));
}
#endregion
_targetType = _owningObjectFactory.GetType(TargetObjectName);
}
}
#endregion
#region Methods
/// <summary>
/// Subclasses should use this method to create a new prototype instance.
/// </summary>
protected virtual object NewPrototypeInstance()
{
#region Instrumentation
if (logger.IsDebugEnabled)
{
logger.Debug(string.Format(
"Creating new target from object '{0}'.",
TargetObjectName));
}
#endregion
return ObjectFactory.GetObject(TargetObjectName);
}
/// <summary>
/// Returns the target object.
/// </summary>
/// <returns>The target object.</returns>
/// <exception cref="System.Exception">
/// If unable to obtain the target object.
/// </exception>
public abstract object GetTarget();
/// <summary>
/// Releases the target object.
/// </summary>
/// <param name="target">The target object to release.</param>
public virtual void ReleaseTarget(object target)
{
}
/// <summary>
/// Invoked by an <see cref="Spring.Objects.Factory.IObjectFactory"/>
/// after it has set all object properties supplied
/// (and satisfied the
/// <see cref="Spring.Objects.Factory.IObjectFactoryAware"/>
/// and <see cref="Spring.Context.IApplicationContextAware"/>
/// interfaces).
/// </summary>
/// <remarks>
/// <p>
/// Ensures that the <see cref="TargetObjectName"/> property has been
/// set to a valid value (i.e. is not <see langword="null"/> or a string
/// that consists solely of whitespace).
/// </p>
/// </remarks>
/// <exception cref="System.Exception">
/// In the event of misconfiguration (such as failure to set an essential
/// property) or if initialization fails.
/// </exception>
/// <seealso cref="Spring.Objects.Factory.IInitializingObject.AfterPropertiesSet"/>
public virtual void AfterPropertiesSet()
{
AssertUtils.ArgumentHasText(
TargetObjectName, "TargetObjectName",
"The 'TargetObjectName' property must have a value.");
}
#endregion
#region Fields
/// <summary>
/// Returns a textual representation of this target source instance.
/// This implementation returns <see cref="GetDescription"/>
/// </summary>
public override string ToString()
{
return GetDescription();
}
/// <summary>
/// Returns a textual representation of this target source instance
/// </summary>
protected virtual string GetDescription()
{
return string.Format("[{0}:{1}]", this.GetType().Name, this.TargetObjectName);
}
/// <summary>
/// The shared <see cref="Common.Logging.ILog"/> instance for this class (and derived classes).
/// </summary>
protected readonly ILog logger = LogManager.GetLogger(typeof (AbstractPrototypeTargetSource));
private String _targetObjectName;
private IObjectFactory _owningObjectFactory;
private Type _targetType;
#endregion
}
}
|