// ========================================================
namespace Kerosene.ORM.Core.Concrete
{
using Kerosene.Tools;
using System;
using System.Runtime.Serialization;
using System.Text;
// ====================================================
/// <summary>
/// Represents a parameter of a command in an agnostic and generic way.
/// </summary>
[Serializable]
public class KParameterBase : IKParameter
{
bool _IsDisposed = false;
IKParameterCollection _Owner = null;
string _Name = null;
object _Value = null;
/// <summary>
/// Creates a new empty and orphan instance.
/// </summary>
public KParameterBase() { }
/// <summary>
/// Gets whether this instance has been disposed or not.
/// </summary>
public bool IsDisposed
{
get { return _IsDisposed; }
}
/// <summary>
/// Disposes this instance, and removes it from its owner it any.
/// </summary>
public void Dispose()
{
if (!IsDisposed) { OnDispose(true); GC.SuppressFinalize(this); }
}
~KParameterBase()
{
if (!IsDisposed) OnDispose(false);
}
protected virtual void OnDispose(bool disposing)
{
if (!IsDisposed && disposing)
{
if (_Owner != null)
{
var temp = _Owner; _Owner = null;
if (temp != null && !temp.IsDisposed) temp.Remove(this);
}
_Value = null;
}
_IsDisposed = true;
}
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (IsDisposed) throw new ObjectDisposedException(this.ToString());
info.AddValue("Name", _Name);
info.AddExtended("Value", _Value);
}
protected KParameterBase(SerializationInfo info, StreamingContext context)
{
_Name = info.GetString("Name");
_Value = info.GetExtended("Value");
}
/// <summary>
/// Returns a new orphan instance that otherwise is a copy of the current one.
/// </summary>
public KParameterBase Clone()
{
if (IsDisposed) throw new ObjectDisposedException(this.ToString());
var cloned = new KParameterBase();
OnClone(cloned); return cloned;
}
IKParameter IKParameter.Clone()
{
return this.Clone();
}
object ICloneable.Clone()
{
return this.Clone();
}
protected virtual void OnClone(object cloned)
{
var temp = (KParameterBase)cloned;
temp._Name = _Name;
temp._Value = _Value.TryClone();
}
/// <summary>
/// Returns whether this instance can be considered equivalent to the other one given.
/// </summary>
/// <param name="other">The other one to compare this one with.</param>
public bool Equals(KParameterBase other)
{
if (object.ReferenceEquals(this, other)) return true;
if (object.ReferenceEquals(null, other)) return false;
if (this.IsDisposed) return false;
if (other.IsDisposed) return false;
var sensitive = _Owner == null ? IKParameterCollectionHelper.DefaultCaseSensitive : _Owner.CaseSensitive;
if (string.Compare(_Name, other._Name, ignoreCase: !sensitive) != 0) return false;
if (!_Value.EquivalentTo(other._Value)) return false;
return true;
}
bool IEquatable<IKParameter>.Equals(IKParameter other)
{
if (Object.ReferenceEquals(this, other)) return true;
if (Object.ReferenceEquals(null, other)) return false;
var temp = other as KParameterBase; if (Object.ReferenceEquals(null, temp)) return false;
return Equals(temp);
}
public override bool Equals(object other)
{
if (Object.ReferenceEquals(this, other)) return true;
if (Object.ReferenceEquals(null, other)) return false;
var temp = other as KParameterBase; if (Object.ReferenceEquals(null, temp)) return false;
return Equals(temp);
}
public override int GetHashCode()
{
return ToString().GetHashCode();
}
public static bool operator ==(KParameterBase left, KParameterBase right)
{
if (object.ReferenceEquals(left, null) && object.ReferenceEquals(right, null)) return true;
if (object.ReferenceEquals(left, null) && !object.ReferenceEquals(right, null)) return false;
if (!object.ReferenceEquals(left, null) && object.ReferenceEquals(right, null)) return false;
if (object.ReferenceEquals(left, right)) return true;
return left.Equals(right);
}
public static bool operator !=(KParameterBase left, KParameterBase right)
{
return !(left == right);
}
/// <summary>
/// Returns the string representation of this instance.
/// </summary>
public override string ToString()
{
StringBuilder sb = new StringBuilder();
if (IsDisposed) sb.Append("disposed::[");
sb.AppendFormat("{0} = '{1}'",
_Name ?? "-",
_Value == null ? "-" : _Value.Sketch());
if (IsDisposed) sb.Append("]");
return sb.ToString();
}
/// <summary>
/// Gets the collection this parameter belongs to, or null if it is an orphan instance.
/// </summary>
public IKParameterCollection Owner
{
get { return _Owner; }
set
{
if (value == null)
{
var temp = _Owner; _Owner = null;
if (temp != null && !temp.IsDisposed) temp.Remove(this);
}
else
{
if (IsDisposed) throw new ObjectDisposedException(this.ToString());
if (object.ReferenceEquals(_Owner, value)) return;
if (value.IndexOf(this) < 0) value.Add(this);
}
_Owner = value;
}
}
/// <summary>
/// Gets the name of this parameter.
/// <para>The setter fails if this instance is not an orphan one.</para>
/// </summary>
public string Name
{
get { return _Name; }
set
{
if (IsDisposed) throw new ObjectDisposedException(this.ToString());
if (Owner != null) throw new NotOrphanException(string.Format("This '{0}' is not orphan.", this));
_Name = IKParameterHelper.ValidateName(value);
}
}
/// <summary>
/// Gets the value this parameter carries.
/// <para>The setter can be used even if this instance is not an orphan one in order to permit the command
/// it is associated with to be reused without the need it to be parsed again.</para>
/// </summary>
public object Value
{
get { return _Value; }
set { _Value = value; }
}
}
}
// ========================================================