performance improvements
fixed SynchronizedHashtable SPRNET-974: support private ctors with ConstructorNode SPRNET-975: treat alias case insensitive as well SPRNET-976: defered registering WebObjectFactory event handlers with VirtualEnvironment to when they are really needed SPRNET-977: avoid unnecessary usages of HttpContextSwitch in WebObjectFactory.ConfigureObject() added tests added VirtualEnvironment HttpSessionState/HttpRequest abstraction
This commit is contained in:
@@ -211,12 +211,12 @@ Global
|
||||
{E2689B4A-A951-420E-A274-BE5EBCD5F8D8}.Release-1.1.Build.0 = Release-1.1|.NET
|
||||
{2E12AE3E-5690-46A5-9F89-80F1D3004ADB}.Debug.ActiveCfg = Debug|.NET
|
||||
{2E12AE3E-5690-46A5-9F89-80F1D3004ADB}.Debug.Build.0 = Debug|.NET
|
||||
{2E12AE3E-5690-46A5-9F89-80F1D3004ADB}.Debug-1.1.ActiveCfg = Debug|.NET
|
||||
{2E12AE3E-5690-46A5-9F89-80F1D3004ADB}.Debug-1.1.Build.0 = Debug|.NET
|
||||
{2E12AE3E-5690-46A5-9F89-80F1D3004ADB}.Debug-1.1.ActiveCfg = Debug-1.1|.NET
|
||||
{2E12AE3E-5690-46A5-9F89-80F1D3004ADB}.Debug-1.1.Build.0 = Debug-1.1|.NET
|
||||
{2E12AE3E-5690-46A5-9F89-80F1D3004ADB}.Release.ActiveCfg = Release|.NET
|
||||
{2E12AE3E-5690-46A5-9F89-80F1D3004ADB}.Release.Build.0 = Release|.NET
|
||||
{2E12AE3E-5690-46A5-9F89-80F1D3004ADB}.Release-1.1.ActiveCfg = Release|.NET
|
||||
{2E12AE3E-5690-46A5-9F89-80F1D3004ADB}.Release-1.1.Build.0 = Release|.NET
|
||||
{2E12AE3E-5690-46A5-9F89-80F1D3004ADB}.Release-1.1.ActiveCfg = Release-1.1|.NET
|
||||
{2E12AE3E-5690-46A5-9F89-80F1D3004ADB}.Release-1.1.Build.0 = Release-1.1|.NET
|
||||
{C17B27C2-4343-45BA-9A21-73C3CEC19BAD}.Debug.ActiveCfg = Debug|.NET
|
||||
{C17B27C2-4343-45BA-9A21-73C3CEC19BAD}.Debug.Build.0 = Debug|.NET
|
||||
{C17B27C2-4343-45BA-9A21-73C3CEC19BAD}.Debug-1.1.ActiveCfg = Debug|.NET
|
||||
|
||||
@@ -318,7 +318,6 @@ Global
|
||||
{130E1609-45A7-4F65-B112-105F2DD3E2CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{130E1609-45A7-4F65-B112-105F2DD3E2CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{130E1609-45A7-4F65-B112-105F2DD3E2CE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{130E1609-45A7-4F65-B112-105F2DD3E2CE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{130E1609-45A7-4F65-B112-105F2DD3E2CE}.Release|.NET.ActiveCfg = Release|Any CPU
|
||||
{130E1609-45A7-4F65-B112-105F2DD3E2CE}.Release|.NET.Build.0 = Release|Any CPU
|
||||
{130E1609-45A7-4F65-B112-105F2DD3E2CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@@ -330,7 +329,6 @@ Global
|
||||
{4A07E150-ED90-407C-8CAD-4760444DDFD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4A07E150-ED90-407C-8CAD-4760444DDFD9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4A07E150-ED90-407C-8CAD-4760444DDFD9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{4A07E150-ED90-407C-8CAD-4760444DDFD9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{4A07E150-ED90-407C-8CAD-4760444DDFD9}.Release|.NET.ActiveCfg = Release|Any CPU
|
||||
{4A07E150-ED90-407C-8CAD-4760444DDFD9}.Release|.NET.Build.0 = Release|Any CPU
|
||||
{4A07E150-ED90-407C-8CAD-4760444DDFD9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@@ -354,7 +352,6 @@ Global
|
||||
{94E4E1B4-D424-4EB9-BF34-2EE8CC3D7048}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{94E4E1B4-D424-4EB9-BF34-2EE8CC3D7048}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{94E4E1B4-D424-4EB9-BF34-2EE8CC3D7048}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{94E4E1B4-D424-4EB9-BF34-2EE8CC3D7048}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{94E4E1B4-D424-4EB9-BF34-2EE8CC3D7048}.Release|.NET.ActiveCfg = Release|Any CPU
|
||||
{94E4E1B4-D424-4EB9-BF34-2EE8CC3D7048}.Release|.NET.Build.0 = Release|Any CPU
|
||||
{94E4E1B4-D424-4EB9-BF34-2EE8CC3D7048}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@@ -397,7 +394,6 @@ Global
|
||||
{AEB1578C-9018-4D49-B440-789F38DD2F29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AEB1578C-9018-4D49-B440-789F38DD2F29}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AEB1578C-9018-4D49-B440-789F38DD2F29}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{AEB1578C-9018-4D49-B440-789F38DD2F29}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{AEB1578C-9018-4D49-B440-789F38DD2F29}.Release|.NET.ActiveCfg = Release|Any CPU
|
||||
{AEB1578C-9018-4D49-B440-789F38DD2F29}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AEB1578C-9018-4D49-B440-789F38DD2F29}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
@@ -407,7 +403,6 @@ Global
|
||||
{FA7A6931-7DBE-4A32-A312-51FAD2E80332}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FA7A6931-7DBE-4A32-A312-51FAD2E80332}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FA7A6931-7DBE-4A32-A312-51FAD2E80332}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{FA7A6931-7DBE-4A32-A312-51FAD2E80332}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{FA7A6931-7DBE-4A32-A312-51FAD2E80332}.Release|.NET.ActiveCfg = Release|Any CPU
|
||||
{FA7A6931-7DBE-4A32-A312-51FAD2E80332}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FA7A6931-7DBE-4A32-A312-51FAD2E80332}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
using System.Collections;
|
||||
using System.Globalization;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Collections
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a performance improved hashtable with case-insensitive (string-only! based) key handling.
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public class CaseInsensitiveHashtable : Hashtable
|
||||
{
|
||||
private readonly TextInfo _textInfo;
|
||||
private readonly CompareInfo _compareInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a case-insensitive hashtable using <see cref="CultureInfo.CurrentCulture"/>.
|
||||
/// </summary>
|
||||
public CaseInsensitiveHashtable()
|
||||
: this(null, CultureInfo.CurrentCulture)
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a case-insensitive hashtable using the given <see cref="CultureInfo"/>.
|
||||
/// </summary>
|
||||
/// <param name="culture">the <see cref="CultureInfo"/> to calculate the hashcode</param>
|
||||
public CaseInsensitiveHashtable(CultureInfo culture)
|
||||
: this(null, culture)
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a case-insensitive hashtable using the given <see cref="CultureInfo"/>, initially
|
||||
/// populated with entries from another dictionary.
|
||||
/// </summary>
|
||||
/// <param name="d">the dictionary to copy entries from</param>
|
||||
/// <param name="culture">the <see cref="CultureInfo"/> to calculate the hashcode</param>
|
||||
public CaseInsensitiveHashtable(IDictionary d, CultureInfo culture)
|
||||
:this(d, culture.TextInfo, culture.CompareInfo)
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a case-insensitive hashtable using the given <see cref="CultureInfo"/>, initially
|
||||
/// populated with entries from another dictionary.
|
||||
/// </summary>
|
||||
protected CaseInsensitiveHashtable(IDictionary d, TextInfo textInfo, CompareInfo compareInfo)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(textInfo, "textInfo");
|
||||
_textInfo = textInfo;
|
||||
_compareInfo = compareInfo;
|
||||
|
||||
if (d != null)
|
||||
{
|
||||
IDictionaryEnumerator enumerator = d.GetEnumerator();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
this.Add(enumerator.Key, enumerator.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the hashcode of the given string key, using the configured culture.
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
protected override int GetHash(object key)
|
||||
{
|
||||
return _textInfo.ToLower((string) key).GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two keys
|
||||
/// </summary>
|
||||
protected override bool KeyEquals(object item, object key)
|
||||
{
|
||||
return 0==_compareInfo.Compare((string) item, (string) key, CompareOptions.IgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a shallow copy of the current instance.
|
||||
/// </summary>
|
||||
public override object Clone()
|
||||
{
|
||||
return new CaseInsensitiveHashtable(this, _textInfo, _compareInfo );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,366 +1,397 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2004 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.Collections;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Collections
|
||||
{
|
||||
/// <summary>
|
||||
/// Synchronized <see cref="Hashtable"/> that, unlike hashtable created
|
||||
/// using <see cref="Hashtable.Synchronized"/> method, synchronizes
|
||||
/// reads from the underlying hashtable in addition to writes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// In addition to synchronizing reads, this implementation also fixes
|
||||
/// IEnumerator/ICollection issue described at
|
||||
/// http://msdn.microsoft.com/en-us/netframework/aa570326.aspx
|
||||
/// (search for SynchronizedHashtable for issue description), by implementing
|
||||
/// <see cref="IEnumerator"/> interface explicitly, and returns thread safe enumerator
|
||||
/// implementations as well.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// This class should be used whenever a truly synchronized <see cref="Hashtable"/>
|
||||
/// is needed.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
[Serializable]
|
||||
public class SynchronizedHashtable : IDictionary, ICollection, IEnumerable, ICloneable
|
||||
{
|
||||
private readonly Hashtable _table;
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="SynchronizedHashtable"/>
|
||||
/// </summary>
|
||||
public SynchronizedHashtable()
|
||||
{
|
||||
this._table = new Hashtable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="SynchronizedHashtable"/>, copying inital entries from <param name="dictionary"/>.
|
||||
/// </summary>
|
||||
public SynchronizedHashtable(IDictionary dictionary)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(dictionary, "dictionary");
|
||||
this._table = new Hashtable(dictionary);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
///<summary>
|
||||
///Gets a value indicating whether the <see cref="T:System.Collections.IDictionary"></see> object is read-only.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///true if the <see cref="T:System.Collections.IDictionary"></see> object is read-only; otherwise, false.
|
||||
///</returns>
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _table.IsReadOnly;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Gets a value indicating whether the <see cref="T:System.Collections.IDictionary"></see> object has a fixed size.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///true if the <see cref="T:System.Collections.IDictionary"></see> object has a fixed size; otherwise, false.
|
||||
///</returns>
|
||||
public bool IsFixedSize
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _table.IsFixedSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Gets a value indicating whether access to the <see cref="T:System.Collections.ICollection"></see> is synchronized (thread safe).
|
||||
///</summary>
|
||||
///<returns>
|
||||
///true if access to the <see cref="T:System.Collections.ICollection"></see> is synchronized (thread safe); otherwise, false.
|
||||
///</returns>
|
||||
public bool IsSynchronized
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Gets an <see cref="T:System.Collections.ICollection"></see> object containing the keys of the <see cref="T:System.Collections.IDictionary"></see> object.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///An <see cref="T:System.Collections.ICollection"></see> object containing the keys of the <see cref="T:System.Collections.IDictionary"></see> object.
|
||||
///</returns>
|
||||
public ICollection Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _table.Keys;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Gets an <see cref="T:System.Collections.ICollection"></see> object containing the values in the <see cref="T:System.Collections.IDictionary"></see> object.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///An <see cref="T:System.Collections.ICollection"></see> object containing the values in the <see cref="T:System.Collections.IDictionary"></see> object.
|
||||
///</returns>
|
||||
public ICollection Values
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _table.Values;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Gets an object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"></see>.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///An object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"></see>.
|
||||
///</returns>
|
||||
public object SyncRoot
|
||||
{
|
||||
get { return _table.SyncRoot; }
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Gets the number of elements contained in the <see cref="T:System.Collections.ICollection"></see>.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///The number of elements contained in the <see cref="T:System.Collections.ICollection"></see>.
|
||||
///</returns>
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _table.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
///<summary>
|
||||
///Adds an element with the provided key and value to the <see cref="T:System.Collections.IDictionary"></see> object.
|
||||
///</summary>
|
||||
///<param name="value">The <see cref="T:System.Object"></see> to use as the value of the element to add. </param>
|
||||
///<param name="key">The <see cref="T:System.Object"></see> to use as the key of the element to add. </param>
|
||||
///<exception cref="T:System.ArgumentException">An element with the same key already exists in the <see cref="T:System.Collections.IDictionary"></see> object. </exception>
|
||||
///<exception cref="T:System.ArgumentNullException">key is null. </exception>
|
||||
///<exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.IDictionary"></see> is read-only.-or- The <see cref="T:System.Collections.IDictionary"></see> has a fixed size. </exception><filterpriority>2</filterpriority>
|
||||
public void Add(object key, object value)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
_table.Add(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Removes all elements from the <see cref="T:System.Collections.IDictionary"></see> object.
|
||||
///</summary>
|
||||
///<exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.IDictionary"></see> object is read-only. </exception><filterpriority>2</filterpriority>
|
||||
public void Clear()
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
_table.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Creates a new object that is a copy of the current instance.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///A new object that is a copy of this instance.
|
||||
///</returns>
|
||||
public object Clone()
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return new SynchronizedHashtable(this);
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Determines whether the <see cref="T:System.Collections.IDictionary"></see> object contains an element with the specified key.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///true if the <see cref="T:System.Collections.IDictionary"></see> contains an element with the key; otherwise, false.
|
||||
///</returns>
|
||||
///<param name="key">The key to locate in the <see cref="T:System.Collections.IDictionary"></see> object.</param>
|
||||
///<exception cref="T:System.ArgumentNullException">key is null. </exception><filterpriority>2</filterpriority>
|
||||
public bool Contains(object key)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _table.Contains(key);
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// Returns, whether this <see cref="IDictionary"/> contains an entry with the specified <paramref name="key"/>.
|
||||
///</summary>
|
||||
///<param name="key">The key to look for</param>
|
||||
///<returns><see lang="true"/>, if this <see cref="IDictionary"/> contains an entry with this <paramref name="key"/></returns>
|
||||
public bool ContainsKey(object key)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _table.ContainsKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// Returns, whether this <see cref="IDictionary"/> contains an entry with the specified <paramref name="value"/>.
|
||||
///</summary>
|
||||
///<param name="value">The val<61>e to look for</param>
|
||||
///<returns><see lang="true"/>, if this <see cref="IDictionary"/> contains an entry with this <paramref name="value"/></returns>
|
||||
public bool ContainsValue(object value)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _table.ContainsValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Copies the elements of the <see cref="T:System.Collections.ICollection"></see> to an <see cref="T:System.Array"></see>, starting at a particular <see cref="T:System.Array"></see> index.
|
||||
///</summary>
|
||||
///<param name="array">The one-dimensional <see cref="T:System.Array"></see> that is the destination of the elements copied from <see cref="T:System.Collections.ICollection"></see>. The <see cref="T:System.Array"></see> must have zero-based indexing. </param>
|
||||
///<param name="index">The zero-based index in array at which copying begins. </param>
|
||||
///<exception cref="T:System.ArgumentNullException">array is null. </exception>
|
||||
///<exception cref="T:System.ArgumentException">The type of the source <see cref="T:System.Collections.ICollection"></see> cannot be cast automatically to the type of the destination array. </exception>
|
||||
///<exception cref="T:System.ArgumentOutOfRangeException">index is less than zero. </exception>
|
||||
///<exception cref="T:System.ArgumentException">array is multidimensional.-or- index is equal to or greater than the length of array.-or- The number of elements in the source <see cref="T:System.Collections.ICollection"></see> is greater than the available space from index to the end of the destination array. </exception><filterpriority>2</filterpriority>
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
_table.CopyTo(array, index);
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Returns an <see cref="T:System.Collections.IDictionaryEnumerator"></see> object for the <see cref="T:System.Collections.IDictionary"></see> object.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///An <see cref="T:System.Collections.IDictionaryEnumerator"></see> object for the <see cref="T:System.Collections.IDictionary"></see> object.
|
||||
///</returns>
|
||||
public IDictionaryEnumerator GetEnumerator()
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return new SynchronizedDictionaryEnumerator(SyncRoot, _table.GetEnumerator());
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Removes the element with the specified key from the <see cref="T:System.Collections.IDictionary"></see> object.
|
||||
///</summary>
|
||||
///<param name="key">The key of the element to remove. </param>
|
||||
///<exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.IDictionary"></see> object is read-only.-or- The <see cref="T:System.Collections.IDictionary"></see> has a fixed size. </exception>
|
||||
///<exception cref="T:System.ArgumentNullException">key is null. </exception><filterpriority>2</filterpriority>
|
||||
public void Remove(object key)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
_table.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable implementation
|
||||
|
||||
///<summary>
|
||||
///Returns an enumerator that iterates through a collection.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///An <see cref="T:System.Collections.IEnumerator"></see> object that can be used to iterate through the collection.
|
||||
///</returns>
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return new SynchronizedEnumerator(SyncRoot, ((IEnumerable) _table).GetEnumerator());
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Indexer
|
||||
|
||||
///<summary>
|
||||
///Gets or sets the element with the specified key.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///The element with the specified key.
|
||||
///</returns>
|
||||
///<param name="key">The key of the element to get or set. </param>
|
||||
///<exception cref="T:System.NotSupportedException">The property is set and the <see cref="T:System.Collections.IDictionary"></see> object is read-only.-or- The property is set, key does not exist in the collection, and the <see cref="T:System.Collections.IDictionary"></see> has a fixed size. </exception>
|
||||
///<exception cref="T:System.ArgumentNullException">key is null. </exception><filterpriority>2</filterpriority>
|
||||
public object this[object key]
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _table[key];
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
_table[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2004 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.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Collections
|
||||
{
|
||||
/// <summary>
|
||||
/// Synchronized <see cref="Hashtable"/> that, unlike hashtable created
|
||||
/// using <see cref="Hashtable.Synchronized"/> method, synchronizes
|
||||
/// reads from the underlying hashtable in addition to writes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// In addition to synchronizing reads, this implementation also fixes
|
||||
/// IEnumerator/ICollection issue described at
|
||||
/// http://msdn.microsoft.com/en-us/netframework/aa570326.aspx
|
||||
/// (search for SynchronizedHashtable for issue description), by implementing
|
||||
/// <see cref="IEnumerator"/> interface explicitly, and returns thread safe enumerator
|
||||
/// implementations as well.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// This class should be used whenever a truly synchronized <see cref="Hashtable"/>
|
||||
/// is needed.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
[Serializable]
|
||||
public class SynchronizedHashtable : IDictionary, ICollection, IEnumerable, ICloneable
|
||||
{
|
||||
private readonly bool _ignoreCase;
|
||||
private readonly Hashtable _table;
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="SynchronizedHashtable"/>
|
||||
/// </summary>
|
||||
public SynchronizedHashtable()
|
||||
: this(new Hashtable(), false)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="SynchronizedHashtable"/>
|
||||
/// </summary>
|
||||
public SynchronizedHashtable(bool ignoreCase)
|
||||
: this(new Hashtable(), ignoreCase)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="SynchronizedHashtable"/>, copying inital entries from <param name="dictionary"/>
|
||||
/// handling keys depending on <param name="ignoreCase"/>.
|
||||
/// </summary>
|
||||
public SynchronizedHashtable(IDictionary dictionary, bool ignoreCase)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(dictionary, "dictionary");
|
||||
this._table = (ignoreCase) ? CollectionsUtil.CreateCaseInsensitiveHashtable(dictionary) : new Hashtable(dictionary);
|
||||
this._ignoreCase = ignoreCase;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="SynchronizedHashtable"/> instance that
|
||||
/// synchronizes access to the underlying <see cref="Hashtable"/>.
|
||||
/// </summary>
|
||||
/// <param name="other">the hashtable to be synchronized</param>
|
||||
protected SynchronizedHashtable(Hashtable other)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(other, "other");
|
||||
this._table = other;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="SynchronizedHashtable"/> wrapper that synchronizes
|
||||
/// access to the passed <see cref="Hashtable"/>.
|
||||
/// </summary>
|
||||
/// <param name="other">the hashtable to be synchronized</param>
|
||||
public static SynchronizedHashtable Wrap(Hashtable other)
|
||||
{
|
||||
return new SynchronizedHashtable(other);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
///<summary>
|
||||
///Gets a value indicating whether the <see cref="T:System.Collections.IDictionary"></see> object is read-only.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///true if the <see cref="T:System.Collections.IDictionary"></see> object is read-only; otherwise, false.
|
||||
///</returns>
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _table.IsReadOnly;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Gets a value indicating whether the <see cref="T:System.Collections.IDictionary"></see> object has a fixed size.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///true if the <see cref="T:System.Collections.IDictionary"></see> object has a fixed size; otherwise, false.
|
||||
///</returns>
|
||||
public bool IsFixedSize
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _table.IsFixedSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Gets a value indicating whether access to the <see cref="T:System.Collections.ICollection"></see> is synchronized (thread safe).
|
||||
///</summary>
|
||||
///<returns>
|
||||
///true if access to the <see cref="T:System.Collections.ICollection"></see> is synchronized (thread safe); otherwise, false.
|
||||
///</returns>
|
||||
public bool IsSynchronized
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Gets an <see cref="T:System.Collections.ICollection"></see> object containing the keys of the <see cref="T:System.Collections.IDictionary"></see> object.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///An <see cref="T:System.Collections.ICollection"></see> object containing the keys of the <see cref="T:System.Collections.IDictionary"></see> object.
|
||||
///</returns>
|
||||
public ICollection Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _table.Keys;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Gets an <see cref="T:System.Collections.ICollection"></see> object containing the values in the <see cref="T:System.Collections.IDictionary"></see> object.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///An <see cref="T:System.Collections.ICollection"></see> object containing the values in the <see cref="T:System.Collections.IDictionary"></see> object.
|
||||
///</returns>
|
||||
public ICollection Values
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _table.Values;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Gets an object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"></see>.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///An object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"></see>.
|
||||
///</returns>
|
||||
public object SyncRoot
|
||||
{
|
||||
get { return _table.SyncRoot; }
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Gets the number of elements contained in the <see cref="T:System.Collections.ICollection"></see>.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///The number of elements contained in the <see cref="T:System.Collections.ICollection"></see>.
|
||||
///</returns>
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _table.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
///<summary>
|
||||
///Adds an element with the provided key and value to the <see cref="T:System.Collections.IDictionary"></see> object.
|
||||
///</summary>
|
||||
///<param name="value">The <see cref="T:System.Object"></see> to use as the value of the element to add. </param>
|
||||
///<param name="key">The <see cref="T:System.Object"></see> to use as the key of the element to add. </param>
|
||||
///<exception cref="T:System.ArgumentException">An element with the same key already exists in the <see cref="T:System.Collections.IDictionary"></see> object. </exception>
|
||||
///<exception cref="T:System.ArgumentNullException">key is null. </exception>
|
||||
///<exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.IDictionary"></see> is read-only.-or- The <see cref="T:System.Collections.IDictionary"></see> has a fixed size. </exception><filterpriority>2</filterpriority>
|
||||
public void Add(object key, object value)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
_table.Add(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Removes all elements from the <see cref="T:System.Collections.IDictionary"></see> object.
|
||||
///</summary>
|
||||
///<exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.IDictionary"></see> object is read-only. </exception><filterpriority>2</filterpriority>
|
||||
public void Clear()
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
_table.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Creates a new object that is a copy of the current instance.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///A new object that is a copy of this instance.
|
||||
///</returns>
|
||||
public object Clone()
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return new SynchronizedHashtable(this, _ignoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Determines whether the <see cref="T:System.Collections.IDictionary"></see> object contains an element with the specified key.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///true if the <see cref="T:System.Collections.IDictionary"></see> contains an element with the key; otherwise, false.
|
||||
///</returns>
|
||||
///<param name="key">The key to locate in the <see cref="T:System.Collections.IDictionary"></see> object.</param>
|
||||
///<exception cref="T:System.ArgumentNullException">key is null. </exception><filterpriority>2</filterpriority>
|
||||
public bool Contains(object key)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _table.Contains(key);
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// Returns, whether this <see cref="IDictionary"/> contains an entry with the specified <paramref name="key"/>.
|
||||
///</summary>
|
||||
///<param name="key">The key to look for</param>
|
||||
///<returns><see lang="true"/>, if this <see cref="IDictionary"/> contains an entry with this <paramref name="key"/></returns>
|
||||
public bool ContainsKey(object key)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _table.ContainsKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// Returns, whether this <see cref="IDictionary"/> contains an entry with the specified <paramref name="value"/>.
|
||||
///</summary>
|
||||
///<param name="value">The val<61>e to look for</param>
|
||||
///<returns><see lang="true"/>, if this <see cref="IDictionary"/> contains an entry with this <paramref name="value"/></returns>
|
||||
public bool ContainsValue(object value)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _table.ContainsValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Copies the elements of the <see cref="T:System.Collections.ICollection"></see> to an <see cref="T:System.Array"></see>, starting at a particular <see cref="T:System.Array"></see> index.
|
||||
///</summary>
|
||||
///<param name="array">The one-dimensional <see cref="T:System.Array"></see> that is the destination of the elements copied from <see cref="T:System.Collections.ICollection"></see>. The <see cref="T:System.Array"></see> must have zero-based indexing. </param>
|
||||
///<param name="index">The zero-based index in array at which copying begins. </param>
|
||||
///<exception cref="T:System.ArgumentNullException">array is null. </exception>
|
||||
///<exception cref="T:System.ArgumentException">The type of the source <see cref="T:System.Collections.ICollection"></see> cannot be cast automatically to the type of the destination array. </exception>
|
||||
///<exception cref="T:System.ArgumentOutOfRangeException">index is less than zero. </exception>
|
||||
///<exception cref="T:System.ArgumentException">array is multidimensional.-or- index is equal to or greater than the length of array.-or- The number of elements in the source <see cref="T:System.Collections.ICollection"></see> is greater than the available space from index to the end of the destination array. </exception><filterpriority>2</filterpriority>
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
_table.CopyTo(array, index);
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Returns an <see cref="T:System.Collections.IDictionaryEnumerator"></see> object for the <see cref="T:System.Collections.IDictionary"></see> object.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///An <see cref="T:System.Collections.IDictionaryEnumerator"></see> object for the <see cref="T:System.Collections.IDictionary"></see> object.
|
||||
///</returns>
|
||||
public IDictionaryEnumerator GetEnumerator()
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return new SynchronizedDictionaryEnumerator(SyncRoot, _table.GetEnumerator());
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Removes the element with the specified key from the <see cref="T:System.Collections.IDictionary"></see> object.
|
||||
///</summary>
|
||||
///<param name="key">The key of the element to remove. </param>
|
||||
///<exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.IDictionary"></see> object is read-only.-or- The <see cref="T:System.Collections.IDictionary"></see> has a fixed size. </exception>
|
||||
///<exception cref="T:System.ArgumentNullException">key is null. </exception><filterpriority>2</filterpriority>
|
||||
public void Remove(object key)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
_table.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable implementation
|
||||
|
||||
///<summary>
|
||||
///Returns an enumerator that iterates through a collection.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///An <see cref="T:System.Collections.IEnumerator"></see> object that can be used to iterate through the collection.
|
||||
///</returns>
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return new SynchronizedEnumerator(SyncRoot, ((IEnumerable)_table).GetEnumerator());
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Indexer
|
||||
|
||||
///<summary>
|
||||
///Gets or sets the element with the specified key.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///The element with the specified key.
|
||||
///</returns>
|
||||
///<param name="key">The key of the element to get or set. </param>
|
||||
///<exception cref="T:System.NotSupportedException">The property is set and the <see cref="T:System.Collections.IDictionary"></see> object is read-only.-or- The property is set, key does not exist in the collection, and the <see cref="T:System.Collections.IDictionary"></see> has a fixed size. </exception>
|
||||
///<exception cref="T:System.ArgumentNullException">key is null. </exception><filterpriority>2</filterpriority>
|
||||
public object this[object key]
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _table[key];
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
_table[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -180,7 +180,7 @@ namespace Spring.Expressions
|
||||
|
||||
private static ConstructorInfo[] GetCandidateConstructors(Type type, int argCount)
|
||||
{
|
||||
ConstructorInfo[] ctors = type.GetConstructors();
|
||||
ConstructorInfo[] ctors = type.GetConstructors(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
|
||||
ArrayList matches = new ArrayList();
|
||||
|
||||
foreach (ConstructorInfo ctor in ctors)
|
||||
|
||||
@@ -410,11 +410,12 @@ namespace Spring.Objects.Factory
|
||||
public static string TransformedObjectName(string name)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(name, "name", "Object name must not be null.");
|
||||
string objectName = name;
|
||||
if (ObjectFactoryUtils.IsFactoryDereference(objectName))
|
||||
if (!ObjectFactoryUtils.IsFactoryDereference(name))
|
||||
{
|
||||
objectName = objectName.Substring(ObjectFactoryUtils.FactoryObjectPrefix.Length);
|
||||
return name;
|
||||
}
|
||||
|
||||
string objectName = name.Substring(ObjectFactoryUtils.FactoryObjectPrefix.Length);
|
||||
return objectName;
|
||||
}
|
||||
|
||||
@@ -459,8 +460,10 @@ namespace Spring.Objects.Factory
|
||||
public static bool IsFactoryDereference(string name)
|
||||
{
|
||||
return name != null
|
||||
&& name.Length > ObjectFactoryUtils.FactoryObjectPrefix.Length
|
||||
&& name[0] == ObjectFactoryUtils.FactoryObjectPrefix[0]
|
||||
&& name.StartsWith(ObjectFactoryUtils.FactoryObjectPrefix)
|
||||
&& name.Length > ObjectFactoryUtils.FactoryObjectPrefix.Length;
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -162,6 +162,11 @@
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Collections\CaseInsensitiveHashtable.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Collections\DictionarySet.cs"
|
||||
SubType = "Code"
|
||||
|
||||
@@ -103,6 +103,7 @@
|
||||
<Compile Include="Collections\AbstractQueue.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Collections\CaseInsensitiveHashtable.cs" />
|
||||
<Compile Include="Collections\DictionarySet.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
||||
@@ -1,143 +1,144 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2007 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.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Util
|
||||
{
|
||||
/// <summary>
|
||||
/// Use this class for obtaining <see cref="ModuleBuilder"/> instances for dynamic code generation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The purpose of this class is to provide a simple abstraction for creating and managing dynamic assemblies.
|
||||
/// </p>
|
||||
/// <note>
|
||||
/// Using this factory you can't define several modules within a single dynamic assembly - only a simple one2one relation between assembly/module is used.
|
||||
/// </note>
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <p>The following excerpt from <see cref="Spring.Proxy.DynamicProxyManager"/> demonstrates usage:</p>
|
||||
/// <code language="c#">
|
||||
/// public class DynamicProxyManager
|
||||
/// {
|
||||
/// public const string PROXY_ASSEMBLY_NAME = "Spring.Proxy";
|
||||
///
|
||||
/// public static TypeBuilder CreateTypeBuilder(string name, Type baseType)
|
||||
/// {
|
||||
/// // Generates type name
|
||||
/// string typeName = String.Format("{0}.{1}_{2}", PROXY_ASSEMBLY_NAME, name, Guid.NewGuid().ToString("N"));
|
||||
/// ModuleBuilder module = DynamicCodeManager.GetModuleBuilder(PROXY_ASSEMBLY_NAME);
|
||||
/// return module.DefineType(typeName, PROXY_TYPE_ATTRIBUTES);
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <author>Erich Eichinger</author>
|
||||
/// <seealso cref="Spring.Reflection.Dynamic.DynamicReflectionManager"/>
|
||||
/// <seealso cref="Spring.Proxy.DynamicProxyManager"/>
|
||||
/// <seealso cref="Spring.Objects.Factory.Support.MethodInjectingInstantiationStrategy"/>
|
||||
public sealed class DynamicCodeManager
|
||||
{
|
||||
private static readonly Hashtable s_moduleCache = CollectionsUtil.CreateCaseInsensitiveHashtable();
|
||||
|
||||
/// <summary>
|
||||
/// prevent instantiation
|
||||
/// </summary>
|
||||
private DynamicCodeManager()
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="ModuleBuilder"/> for the dynamic module within the specified assembly.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the assembly does not exist yet, it will be created.<br/>
|
||||
/// This factory caches any dynamic assembly it creates - calling GetModule() twice with
|
||||
/// the same name will *not* create 2 distinct modules!
|
||||
/// </remarks>
|
||||
/// <param name="assemblyName">The assembly-name of the module to be returned</param>
|
||||
/// <returns>the <see cref="ModuleBuilder"/> that can be used to define new types within the specified assembly</returns>
|
||||
public static ModuleBuilder GetModuleBuilder( string assemblyName )
|
||||
{
|
||||
lock(s_moduleCache.SyncRoot)
|
||||
{
|
||||
ModuleBuilder module = (ModuleBuilder) s_moduleCache[assemblyName];
|
||||
if (module == null)
|
||||
{
|
||||
AssemblyName an = new AssemblyName();
|
||||
an.Name = assemblyName;
|
||||
|
||||
AssemblyBuilder assembly;
|
||||
#if DEBUG_DYNAMIC
|
||||
assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave, null, null, null, null,null, true );
|
||||
module = assembly.DefineDynamicModule(an.Name, an.Name + ".dll", true);
|
||||
#else
|
||||
assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run, null, null, null, null,null, true );
|
||||
#if DEBUG
|
||||
module = assembly.DefineDynamicModule(an.Name, true);
|
||||
#else
|
||||
module = assembly.DefineDynamicModule(an.Name, false);
|
||||
#endif
|
||||
#endif
|
||||
s_moduleCache[assemblyName] = module;
|
||||
}
|
||||
return module;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Persists the specified dynamic assembly to the file-system
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">the name of the dynamic assembly to persist</param>
|
||||
/// <remarks>
|
||||
/// Can only be called in DEBUG_DYNAMIC mode, per ConditionalAttribute rules.
|
||||
/// </remarks>
|
||||
[Conditional("DEBUG_DYNAMIC")]
|
||||
public static void SaveAssembly( string assemblyName )
|
||||
{
|
||||
AssertUtils.ArgumentHasText(assemblyName, "assemblyName");
|
||||
|
||||
ModuleBuilder module = null;
|
||||
lock(s_moduleCache.SyncRoot)
|
||||
{
|
||||
module = (ModuleBuilder) s_moduleCache[assemblyName];
|
||||
}
|
||||
|
||||
if(module == null)
|
||||
{
|
||||
throw new ArgumentException(string.Format("'{0}' is not a valid dynamic assembly name", assemblyName), "assemblyName");
|
||||
}
|
||||
|
||||
AssemblyBuilder assembly = (AssemblyBuilder) module.Assembly;
|
||||
assembly.Save(assembly.GetName().Name + ".dll");
|
||||
}
|
||||
}
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2007 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.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using Spring.Collections;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Util
|
||||
{
|
||||
/// <summary>
|
||||
/// Use this class for obtaining <see cref="ModuleBuilder"/> instances for dynamic code generation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The purpose of this class is to provide a simple abstraction for creating and managing dynamic assemblies.
|
||||
/// </p>
|
||||
/// <note>
|
||||
/// Using this factory you can't define several modules within a single dynamic assembly - only a simple one2one relation between assembly/module is used.
|
||||
/// </note>
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <p>The following excerpt from <see cref="Spring.Proxy.DynamicProxyManager"/> demonstrates usage:</p>
|
||||
/// <code language="c#">
|
||||
/// public class DynamicProxyManager
|
||||
/// {
|
||||
/// public const string PROXY_ASSEMBLY_NAME = "Spring.Proxy";
|
||||
///
|
||||
/// public static TypeBuilder CreateTypeBuilder(string name, Type baseType)
|
||||
/// {
|
||||
/// // Generates type name
|
||||
/// string typeName = String.Format("{0}.{1}_{2}", PROXY_ASSEMBLY_NAME, name, Guid.NewGuid().ToString("N"));
|
||||
/// ModuleBuilder module = DynamicCodeManager.GetModuleBuilder(PROXY_ASSEMBLY_NAME);
|
||||
/// return module.DefineType(typeName, PROXY_TYPE_ATTRIBUTES);
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <author>Erich Eichinger</author>
|
||||
/// <seealso cref="Spring.Reflection.Dynamic.DynamicReflectionManager"/>
|
||||
/// <seealso cref="Spring.Proxy.DynamicProxyManager"/>
|
||||
/// <seealso cref="Spring.Objects.Factory.Support.MethodInjectingInstantiationStrategy"/>
|
||||
public sealed class DynamicCodeManager
|
||||
{
|
||||
private static readonly Hashtable s_moduleCache = new CaseInsensitiveHashtable(); //CollectionsUtil.CreateCaseInsensitiveHashtable();
|
||||
|
||||
/// <summary>
|
||||
/// prevent instantiation
|
||||
/// </summary>
|
||||
private DynamicCodeManager()
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="ModuleBuilder"/> for the dynamic module within the specified assembly.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the assembly does not exist yet, it will be created.<br/>
|
||||
/// This factory caches any dynamic assembly it creates - calling GetModule() twice with
|
||||
/// the same name will *not* create 2 distinct modules!
|
||||
/// </remarks>
|
||||
/// <param name="assemblyName">The assembly-name of the module to be returned</param>
|
||||
/// <returns>the <see cref="ModuleBuilder"/> that can be used to define new types within the specified assembly</returns>
|
||||
public static ModuleBuilder GetModuleBuilder( string assemblyName )
|
||||
{
|
||||
lock(s_moduleCache.SyncRoot)
|
||||
{
|
||||
ModuleBuilder module = (ModuleBuilder) s_moduleCache[assemblyName];
|
||||
if (module == null)
|
||||
{
|
||||
AssemblyName an = new AssemblyName();
|
||||
an.Name = assemblyName;
|
||||
|
||||
AssemblyBuilder assembly;
|
||||
#if DEBUG_DYNAMIC
|
||||
assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave, null, null, null, null,null, true );
|
||||
module = assembly.DefineDynamicModule(an.Name, an.Name + ".dll", true);
|
||||
#else
|
||||
assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run, null, null, null, null,null, true );
|
||||
#if DEBUG
|
||||
module = assembly.DefineDynamicModule(an.Name, true);
|
||||
#else
|
||||
module = assembly.DefineDynamicModule(an.Name, false);
|
||||
#endif
|
||||
#endif
|
||||
s_moduleCache[assemblyName] = module;
|
||||
}
|
||||
return module;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Persists the specified dynamic assembly to the file-system
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">the name of the dynamic assembly to persist</param>
|
||||
/// <remarks>
|
||||
/// Can only be called in DEBUG_DYNAMIC mode, per ConditionalAttribute rules.
|
||||
/// </remarks>
|
||||
[Conditional("DEBUG_DYNAMIC")]
|
||||
public static void SaveAssembly( string assemblyName )
|
||||
{
|
||||
AssertUtils.ArgumentHasText(assemblyName, "assemblyName");
|
||||
|
||||
ModuleBuilder module = null;
|
||||
lock(s_moduleCache.SyncRoot)
|
||||
{
|
||||
module = (ModuleBuilder) s_moduleCache[assemblyName];
|
||||
}
|
||||
|
||||
if(module == null)
|
||||
{
|
||||
throw new ArgumentException(string.Format("'{0}' is not a valid dynamic assembly name", assemblyName), "assemblyName");
|
||||
}
|
||||
|
||||
AssemblyBuilder assembly = (AssemblyBuilder) module.Assembly;
|
||||
assembly.Save(assembly.GetName().Name + ".dll");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -506,6 +506,11 @@
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Data\Generic\DataAdapterDelegate.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Data\Generic\IAdoOperations.cs"
|
||||
SubType = "Code"
|
||||
@@ -516,6 +521,11 @@
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Data\Generic\IDataAdapterCallback.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Data\Generic\IDbCommandCallback.cs"
|
||||
SubType = "Code"
|
||||
@@ -656,6 +666,11 @@
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Data\Support\DefaultTransactionScopeAdapter.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Data\Support\ErrorCodeExceptionTranslator.cs"
|
||||
SubType = "Code"
|
||||
@@ -676,6 +691,11 @@
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Data\Support\ITransactionScopeAdapter.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Data\Support\NamedResultSetProcessor.cs"
|
||||
SubType = "Code"
|
||||
@@ -949,6 +969,11 @@
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Transaction\Support\IResourceTransactionManager.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Transaction\Support\ISmartTransactionObject.cs"
|
||||
SubType = "Code"
|
||||
|
||||
@@ -28,6 +28,7 @@ using System.Reflection;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using Common.Logging;
|
||||
using Spring.Collections;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
using Spring.Util;
|
||||
@@ -126,7 +127,7 @@ namespace Spring.Context.Support
|
||||
/// Since the HttpRuntime discards it's configurationsection cache, we maintain our own context cache.
|
||||
/// Despite it really speeds up context-lookup, since we don't have to go through the whole HttpConfigurationSystem
|
||||
/// </summary>
|
||||
private static readonly Hashtable s_webContextCache = CollectionsUtil.CreateCaseInsensitiveHashtable();
|
||||
private static readonly Hashtable s_webContextCache = new CaseInsensitiveHashtable(); //CollectionsUtil.CreateCaseInsensitiveHashtable();
|
||||
|
||||
static WebApplicationContext()
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@ using System.Web;
|
||||
using System.Web.Caching;
|
||||
using System.Web.SessionState;
|
||||
using Common.Logging;
|
||||
using Spring.Collections;
|
||||
using Spring.Context.Support;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Util;
|
||||
@@ -50,6 +51,7 @@ namespace Spring.Objects.Factory.Support
|
||||
{
|
||||
private readonly static ILog log = LogManager.GetLogger(typeof(WebObjectFactory));
|
||||
|
||||
private static bool s_eventHandlersRegistered = false;
|
||||
private readonly static string OBJECTTABLEKEY = "spring.objects";
|
||||
|
||||
private delegate IDictionary ObjectDictionaryCreationHandler();
|
||||
@@ -68,7 +70,7 @@ namespace Spring.Objects.Factory.Support
|
||||
|
||||
static WebObjectFactory()
|
||||
{
|
||||
EnsureEventHandlersRegistered();
|
||||
//EnsureEventHandlersRegistered();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -77,9 +79,19 @@ namespace Spring.Objects.Factory.Support
|
||||
/// </summary>
|
||||
private static void EnsureEventHandlersRegistered()
|
||||
{
|
||||
if (log.IsDebugEnabled) log.Debug("hooking up event handlers");
|
||||
VirtualEnvironment.EndRequest += new VirtualEnvironment.RequestEventHandler(OnEndRequest);
|
||||
VirtualEnvironment.EndSession += new VirtualEnvironment.SessionEventHandler(OnEndSession);
|
||||
if (!s_eventHandlersRegistered)
|
||||
{
|
||||
lock(typeof(WebObjectFactory))
|
||||
{
|
||||
if (s_eventHandlersRegistered) return;
|
||||
|
||||
if (log.IsDebugEnabled) log.Debug("hooking up event handlers");
|
||||
VirtualEnvironment.EndRequest += new VirtualEnvironment.RequestEventHandler(OnEndRequest);
|
||||
VirtualEnvironment.EndSession += new VirtualEnvironment.SessionEventHandler(OnEndSession);
|
||||
|
||||
s_eventHandlersRegistered = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -303,6 +315,8 @@ namespace Spring.Objects.Factory.Support
|
||||
object instance;
|
||||
lock (scopedSingletonCache.SyncRoot)
|
||||
{
|
||||
EnsureEventHandlersRegistered();
|
||||
|
||||
instance = scopedSingletonCache[objectName];
|
||||
if (instance == TemporarySingletonPlaceHolder)
|
||||
{
|
||||
@@ -397,23 +411,26 @@ namespace Spring.Objects.Factory.Support
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Injects dependencies into the supplied <paramref name="target"/> instance
|
||||
/// using the named object definition.
|
||||
/// Configures object instance by injecting dependencies, satisfying Spring lifecycle
|
||||
/// interfaces and applying object post-processors.
|
||||
/// </summary>
|
||||
/// <param name="target">
|
||||
/// The object instance that is to be so configured.
|
||||
/// </param>
|
||||
/// <param name="name">
|
||||
/// The name of the object definition expressing the dependencies that are to
|
||||
/// be injected into the supplied <parameref name="target"/> instance.
|
||||
/// </param>
|
||||
/// <param name="definition">
|
||||
/// An object definition that should be used to configure object.
|
||||
/// </param>
|
||||
/// <param name="wrapper">
|
||||
/// A wrapped object instance that is to be so configured.
|
||||
/// </param>
|
||||
/// <seealso cref="Spring.Objects.Factory.IObjectFactory.ConfigureObject(object, string)"/>
|
||||
public override object ConfigureObject(object target, string name)
|
||||
protected override object ConfigureObject(string name, RootObjectDefinition definition, IObjectWrapper wrapper)
|
||||
{
|
||||
// always configure object relative to contextPath
|
||||
using (new HttpContextSwitch(contextPath))
|
||||
{
|
||||
return base.ConfigureObject(target, name);
|
||||
return base.ConfigureObject(name, definition, wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,7 +499,7 @@ namespace Spring.Objects.Factory.Support
|
||||
/// </summary>
|
||||
private static IDictionary CreateCaseInsensitiveDictionary()
|
||||
{
|
||||
return CollectionsUtil.CreateCaseInsensitiveHashtable();
|
||||
return new CaseInsensitiveHashtable(); //CollectionsUtil.CreateCaseInsensitiveHashtable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -275,6 +275,11 @@
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Util\ISessionState.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Util\IVirtualEnvironment.cs"
|
||||
SubType = "Code"
|
||||
|
||||
@@ -122,6 +122,7 @@
|
||||
<Compile Include="Globalization\AspNetResourceCache.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Util\ISessionState.cs" />
|
||||
<Compile Include="Web\UI\IValidationContainer.cs" />
|
||||
<Compile Include="Web\Support\MimeMediaType.cs" />
|
||||
<Compile Include="Web\Support\SharedStateResourceCache.cs">
|
||||
|
||||
48
src/Spring/Spring.Web/Util/ISessionState.cs
Normal file
48
src/Spring/Spring.Web/Util/ISessionState.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System.Collections;
|
||||
using System.Web;
|
||||
using System.Web.SessionState;
|
||||
|
||||
namespace Spring.Util
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstracts HttpSession
|
||||
/// </summary>
|
||||
public interface ISessionState : IDictionary
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="System.Web.SessionState.HttpSessionState.Abandon"/>
|
||||
/// </summary>
|
||||
void Abandon();
|
||||
/// <summary>
|
||||
/// <see cref="System.Web.SessionState.HttpSessionState.IsCookieless"/>
|
||||
/// </summary>
|
||||
bool IsCookieless { get; }
|
||||
/// <summary>
|
||||
/// <see cref="System.Web.SessionState.HttpSessionState.IsNewSession"/>
|
||||
/// </summary>
|
||||
bool IsNewSession { get; }
|
||||
/// <summary>
|
||||
/// <see cref="System.Web.SessionState.HttpSessionState.LCID"/>
|
||||
/// </summary>
|
||||
int LCID { get; set; }
|
||||
/// <summary>
|
||||
/// <see cref="System.Web.SessionState.HttpSessionState.Mode"/>
|
||||
/// </summary>
|
||||
SessionStateMode Mode { get; }
|
||||
/// <summary>
|
||||
/// <see cref="System.Web.SessionState.HttpSessionState.SessionID"/>
|
||||
/// </summary>
|
||||
string SessionID { get; }
|
||||
/// <summary>
|
||||
/// <see cref="System.Web.SessionState.HttpSessionState.CodePage"/>
|
||||
/// </summary>
|
||||
int CodePage { get; set; }
|
||||
|
||||
#if NET_2_0
|
||||
/// <summary>
|
||||
/// <see cref="System.Web.SessionState.HttpSessionState.CookieMode"/>
|
||||
/// </summary>
|
||||
HttpCookieMode CookieMode { get; }
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Web;
|
||||
@@ -66,5 +67,14 @@ namespace Spring.Util
|
||||
/// Maps a virtual path to it's physical location
|
||||
/// </summary>
|
||||
string MapPath( string virtualPath );
|
||||
/// <summary>
|
||||
/// Returns the current Session's variable dictionary
|
||||
/// </summary>
|
||||
ISessionState Session { get; }
|
||||
/// <summary>
|
||||
/// Returns the current Request's variable dictionary
|
||||
/// </summary>
|
||||
IDictionary RequestVariables { get; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using System.Web.Caching;
|
||||
@@ -71,16 +72,167 @@ namespace Spring.Util
|
||||
return prevEnvironment;
|
||||
}
|
||||
|
||||
#region default IVirtualEnvironment Adapter for HttpRuntime
|
||||
#region default IVirtualEnvironment Adapter for HttpRuntime
|
||||
|
||||
/// <summary>
|
||||
/// Implementation for running within HttpRuntime
|
||||
/// </summary>
|
||||
private class HttpRuntimeEnvironment : IVirtualEnvironment
|
||||
{
|
||||
#region HttpSessionState Adapter
|
||||
|
||||
private class SessionDictionaryAdapter : ISessionState
|
||||
{
|
||||
private readonly HttpSessionState _sessionState;
|
||||
|
||||
public SessionDictionaryAdapter(HttpSessionState sessionState)
|
||||
{
|
||||
_sessionState = sessionState;
|
||||
}
|
||||
|
||||
|
||||
public bool Contains(object key)
|
||||
{
|
||||
ICollection keys = _sessionState.Keys;
|
||||
foreach (string sessionKey in keys)
|
||||
{
|
||||
if (object.Equals(sessionKey, (string)key)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Add(object key, object value)
|
||||
{
|
||||
_sessionState.Add((string)key, value);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_sessionState.Clear();
|
||||
}
|
||||
|
||||
public IDictionaryEnumerator GetEnumerator()
|
||||
{
|
||||
Hashtable tableCopy = new Hashtable();
|
||||
ICollection keys = _sessionState.Keys;
|
||||
foreach (string sessionKey in keys)
|
||||
{
|
||||
tableCopy.Add(sessionKey, _sessionState[sessionKey]);
|
||||
}
|
||||
return tableCopy.GetEnumerator();
|
||||
}
|
||||
|
||||
public void Remove(object key)
|
||||
{
|
||||
_sessionState.Remove((string) key);
|
||||
}
|
||||
|
||||
public object this[object key]
|
||||
{
|
||||
get { return _sessionState[(string)key]; }
|
||||
set { _sessionState[(string)key] = value; }
|
||||
}
|
||||
|
||||
public ICollection Keys
|
||||
{
|
||||
get { return _sessionState.Keys; }
|
||||
}
|
||||
|
||||
public ICollection Values
|
||||
{
|
||||
get
|
||||
{
|
||||
object[] values = new object[_sessionState.Count];
|
||||
_sessionState.CopyTo(values, 0);
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return _sessionState.IsReadOnly; }
|
||||
}
|
||||
|
||||
public bool IsFixedSize
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
_sessionState.CopyTo(array, index);
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return _sessionState.Count; }
|
||||
}
|
||||
|
||||
public object SyncRoot
|
||||
{
|
||||
get { return _sessionState.SyncRoot; }
|
||||
}
|
||||
|
||||
public bool IsSynchronized
|
||||
{
|
||||
get { return _sessionState.IsSynchronized; }
|
||||
}
|
||||
|
||||
public void Abandon()
|
||||
{
|
||||
_sessionState.Abandon();
|
||||
}
|
||||
|
||||
public bool IsCookieless
|
||||
{
|
||||
get { return _sessionState.IsCookieless; }
|
||||
}
|
||||
|
||||
public bool IsNewSession
|
||||
{
|
||||
get { return _sessionState.IsNewSession; }
|
||||
}
|
||||
|
||||
public int LCID
|
||||
{
|
||||
get { return _sessionState.LCID; }
|
||||
set { _sessionState.LCID = value; }
|
||||
}
|
||||
|
||||
public SessionStateMode Mode
|
||||
{
|
||||
get { return _sessionState.Mode; }
|
||||
}
|
||||
|
||||
public string SessionID
|
||||
{
|
||||
get { return _sessionState.SessionID; }
|
||||
}
|
||||
|
||||
public int CodePage
|
||||
{
|
||||
get { return _sessionState.CodePage; }
|
||||
set { _sessionState.CodePage = value; }
|
||||
}
|
||||
#if NET_2_0
|
||||
public HttpCookieMode CookieMode
|
||||
{
|
||||
get { return _sessionState.CookieMode; }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion //HttpSessionState Adapter
|
||||
|
||||
public string ApplicationVirtualPath
|
||||
{
|
||||
get {
|
||||
get
|
||||
{
|
||||
string appPath = HttpRuntime.AppDomainAppVirtualPath;
|
||||
if (!appPath.EndsWith("/")) appPath = appPath + "/";
|
||||
return appPath;
|
||||
@@ -124,6 +276,16 @@ namespace Spring.Util
|
||||
#endif
|
||||
throw new ArgumentException("can't map context relative path outside a context");
|
||||
}
|
||||
|
||||
public ISessionState Session
|
||||
{
|
||||
get { return new SessionDictionaryAdapter(HttpContext.Current.Session); }
|
||||
}
|
||||
|
||||
public IDictionary RequestVariables
|
||||
{
|
||||
get { return HttpContext.Current.Items; }
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -25,6 +25,7 @@ using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Web;
|
||||
using System.Web.SessionState;
|
||||
using Spring.Collections;
|
||||
using Spring.Context;
|
||||
using Spring.Util;
|
||||
using Spring.Web.Process;
|
||||
@@ -52,7 +53,7 @@ namespace Spring.Web.Support
|
||||
private object controller;
|
||||
private string defaultView;
|
||||
private string currentView;
|
||||
private IDictionary views = CollectionsUtil.CreateCaseInsensitiveHashtable();
|
||||
private IDictionary views = new CaseInsensitiveHashtable(); //CollectionsUtil.CreateCaseInsensitiveHashtable();
|
||||
private IDictionary sharedState;
|
||||
private IApplicationContext applicationContext;
|
||||
private string processUrl;
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace Spring.Web.Support
|
||||
{
|
||||
private readonly ILog Log = LogManager.GetLogger(typeof(PageHandlerFactory));
|
||||
|
||||
private readonly IDictionary pageHandlerWrappers = CollectionsUtil.CreateCaseInsensitiveHashtable();
|
||||
private readonly IDictionary pageHandlerWrappers = new CaseInsensitiveHashtable(); //CollectionsUtil.CreateCaseInsensitiveHashtable();
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves instance of the configured page from Spring web application context,
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 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
|
||||
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using NUnit.Framework;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Collections
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
[TestFixture]
|
||||
public class CaseInsensitiveHashtableTests
|
||||
{
|
||||
[Test]
|
||||
public void IgnoresCase()
|
||||
{
|
||||
CaseInsensitiveHashtable st = new CaseInsensitiveHashtable();
|
||||
st.Add("key", "value");
|
||||
Assert.AreEqual("value", st["KEY"]);
|
||||
st["KeY"] = "value2";
|
||||
Assert.AreEqual(1, st.Count);
|
||||
Assert.AreEqual("value2", st["key"]);
|
||||
|
||||
try
|
||||
{
|
||||
st.Add("KEY", "value2");
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{}
|
||||
|
||||
Hashtable ht = new Hashtable();
|
||||
ht.Add("key","value");
|
||||
ht.Add("KEY","value");
|
||||
try
|
||||
{
|
||||
st = new CaseInsensitiveHashtable(ht, CultureInfo.InvariantCulture);
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InitializeFromOtherCopiesValues()
|
||||
{
|
||||
Hashtable ht = new Hashtable();
|
||||
ht["key"] = "value";
|
||||
ht["key2"] = "value2";
|
||||
|
||||
CaseInsensitiveHashtable st = new CaseInsensitiveHashtable(ht, CultureInfo.InvariantCulture);
|
||||
Assert.AreEqual(2, st.Count);
|
||||
ht.Remove("key");
|
||||
Assert.AreEqual(1, ht.Count);
|
||||
Assert.AreEqual(2, st.Count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On my NB gives
|
||||
/// Duration: 00:00:11.0937500
|
||||
/// Duration: 00:00:05.3593750
|
||||
/// </summary>
|
||||
[Test, Explicit]
|
||||
public void ComparePerformance()
|
||||
{
|
||||
const int runs = 30000000;
|
||||
StopWatch watch = new StopWatch();
|
||||
|
||||
Hashtable ht = CollectionsUtil.CreateCaseInsensitiveHashtable();
|
||||
for(int i=0;i<1000000;i++) ht.Add(Guid.NewGuid().ToString(), "val"); // gen. higher number of elements results in OOM exception????
|
||||
CaseInsensitiveHashtable ciht = new CaseInsensitiveHashtable(ht, CultureInfo.InvariantCulture);
|
||||
|
||||
using (watch.Start("Duration: {0}"))
|
||||
{
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
object v = ht["somekey"];
|
||||
}
|
||||
}
|
||||
|
||||
using (watch.Start("Duration: {0}"))
|
||||
{
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
object v = ciht["somekey"];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,10 +37,100 @@ namespace Spring.Collections
|
||||
[TestFixture]
|
||||
public class SynchronizedHashtableTests
|
||||
{
|
||||
[Test]
|
||||
public void BehavesLikeHashtable()
|
||||
{
|
||||
SynchronizedHashtable st = new SynchronizedHashtable();
|
||||
st.Add("key", "value");
|
||||
Assert.AreEqual("value", st["key"]);
|
||||
st["key"] = "value2";
|
||||
Assert.AreEqual("value2", st["key"]);
|
||||
st["key2"] = "value3";
|
||||
Assert.AreEqual("value3", st["key2"]);
|
||||
|
||||
try
|
||||
{
|
||||
st.Add("key", "value4");
|
||||
Assert.Fail();
|
||||
}
|
||||
catch(ArgumentException)
|
||||
{}
|
||||
|
||||
Assert.AreEqual(2, st.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InitializeFromOtherCopiesValues()
|
||||
{
|
||||
Hashtable ht = new Hashtable();
|
||||
ht["key"] = "value";
|
||||
ht["key2"] = "value2";
|
||||
|
||||
SynchronizedHashtable st = new SynchronizedHashtable(ht, false);
|
||||
Assert.AreEqual(2, st.Count);
|
||||
ht.Remove("key");
|
||||
Assert.AreEqual(1, ht.Count);
|
||||
Assert.AreEqual(2, st.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DefaultsToCaseSensitive()
|
||||
{
|
||||
SynchronizedHashtable st = new SynchronizedHashtable();
|
||||
st.Add("key","value");
|
||||
st.Add("KEY","value");
|
||||
Assert.AreEqual(2, st.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IgnoreCaseIgnoresCase()
|
||||
{
|
||||
SynchronizedHashtable st = new SynchronizedHashtable(true);
|
||||
st.Add("key", "value");
|
||||
Assert.AreEqual("value", st["KEY"]);
|
||||
st["KeY"] = "value2";
|
||||
Assert.AreEqual(1, st.Count);
|
||||
Assert.AreEqual("value2", st["key"]);
|
||||
|
||||
try
|
||||
{
|
||||
st.Add("KEY", "value2");
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{}
|
||||
|
||||
Hashtable ht = new Hashtable();
|
||||
ht.Add("key","value");
|
||||
ht.Add("KEY","value");
|
||||
try
|
||||
{
|
||||
st = new SynchronizedHashtable(ht, true);
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WrapKeepsOriginalHashtableReference()
|
||||
{
|
||||
Hashtable ht = new Hashtable();
|
||||
ht["key"] = "value";
|
||||
ht["key2"] = "value2";
|
||||
|
||||
SynchronizedHashtable st = SynchronizedHashtable.Wrap(ht);
|
||||
Assert.AreEqual(2, st.Count);
|
||||
ht.Remove("key");
|
||||
Assert.AreEqual(1, ht.Count);
|
||||
Assert.AreEqual(1, st.Count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On my Notebook gives
|
||||
/// Normal Hashtable: 00:00:01.5937500
|
||||
/// Synced Hashtable: 00:00:02.8593750
|
||||
/// Normal Hashtable: 00:00:00.0937500
|
||||
/// Synced Hashtable: 00:00:00.9375000
|
||||
/// =locking *has* a peformance impact.
|
||||
/// </summary>
|
||||
[Test, Explicit]
|
||||
public void TestLockingPerformanceImpact()
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 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
|
||||
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Expressions
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
[TestFixture]
|
||||
public class ConstructorNodeTests
|
||||
{
|
||||
#region Test Classes
|
||||
|
||||
public class PublicTestClass
|
||||
{
|
||||
public string _s;
|
||||
public int _i;
|
||||
|
||||
public PublicTestClass(string s)
|
||||
:this(s, -1)
|
||||
{}
|
||||
|
||||
protected PublicTestClass(string s, int i)
|
||||
{
|
||||
_s = s; _i=i;
|
||||
}
|
||||
}
|
||||
|
||||
private class PrivateTestClass : PublicTestClass
|
||||
{
|
||||
private PrivateTestClass(string s, int i)
|
||||
:base(s,i)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Test Classes
|
||||
|
||||
[Test]
|
||||
public void CanCreatePublicInstance()
|
||||
{
|
||||
ConstructorNode ctorNode = new ConstructorNode();
|
||||
ctorNode.Text=typeof(PublicTestClass).FullName;
|
||||
StringLiteralNode sNode = new StringLiteralNode();
|
||||
sNode.Text = "theValue";
|
||||
ctorNode.addChild(sNode);
|
||||
|
||||
PublicTestClass instance = (PublicTestClass) ((IExpression)ctorNode).GetValue();
|
||||
Assert.AreEqual( sNode.Text, instance._s );
|
||||
Assert.AreEqual( -1, instance._i );
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanCreatePublicInstanceWithNonPublicConstructor()
|
||||
{
|
||||
ConstructorNode ctorNode = new ConstructorNode();
|
||||
ctorNode.Text=typeof(PublicTestClass).FullName;
|
||||
StringLiteralNode sNode = new StringLiteralNode();
|
||||
sNode.Text = "theValue2";
|
||||
ctorNode.addChild(sNode);
|
||||
IntLiteralNode iNode = new IntLiteralNode();
|
||||
iNode.Text="2";
|
||||
ctorNode.addChild(iNode);
|
||||
|
||||
PublicTestClass instance = (PublicTestClass) ((IExpression)ctorNode).GetValue();
|
||||
Assert.AreEqual( sNode.Text, instance._s );
|
||||
Assert.AreEqual( 2, instance._i );
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanCreateNonPublicInstanceWithNonPublicConstructor()
|
||||
{
|
||||
ConstructorNode ctorNode = new ConstructorNode();
|
||||
ctorNode.Text=typeof(PrivateTestClass).FullName;
|
||||
StringLiteralNode sNode = new StringLiteralNode();
|
||||
sNode.Text = "theValue3";
|
||||
ctorNode.addChild(sNode);
|
||||
IntLiteralNode iNode = new IntLiteralNode();
|
||||
iNode.Text="3";
|
||||
ctorNode.addChild(iNode);
|
||||
|
||||
PublicTestClass instance = (PublicTestClass) ((IExpression)ctorNode).GetValue();
|
||||
Assert.AreEqual( sNode.Text, instance._s );
|
||||
Assert.AreEqual( 3, instance._i );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,12 +22,51 @@
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Objects.Factory.Support;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Objects.Factory
|
||||
{
|
||||
public class TestAbstractObjectFactory : AbstractObjectFactory
|
||||
{
|
||||
protected override object CreateObject(string name, RootObjectDefinition definition, object[] arguments)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
protected override void DestroyObject(string name, object target)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool ContainsObjectDefinition(string name)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override IObjectDefinition GetObjectDefinition(string name)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override IObjectDefinition GetObjectDefinition(string name, bool includeAncestors)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override object ConfigureObject(object target, string name)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override object ConfigureObject(object target, string name, IObjectDefinition definition)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subclasses must override SetUp () to initialize the object factory
|
||||
/// and any other variables they need.
|
||||
@@ -38,13 +77,43 @@ namespace Spring.Objects.Factory
|
||||
{
|
||||
#region Properties
|
||||
|
||||
protected internal abstract IObjectFactory ObjectFactory { get; }
|
||||
protected internal abstract AbstractObjectFactory CreateObjectFactory(bool caseSensitive);
|
||||
|
||||
#endregion
|
||||
protected AbstractObjectFactory ObjectFactory { get { return CreateObjectFactory(true); } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tests
|
||||
#region Case Insensitive Tests
|
||||
|
||||
/// <summary>
|
||||
[Test]
|
||||
public void RespectsCaseInsensitiveNamesAndAliases()
|
||||
{
|
||||
AbstractObjectFactory of = CreateObjectFactory(false);
|
||||
|
||||
object testObject = new object();
|
||||
of.RegisterSingleton("name", testObject);
|
||||
of.RegisterAlias("NAME", "alias");
|
||||
|
||||
try
|
||||
{
|
||||
of.RegisterAlias("NaMe", "AlIaS");
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (ObjectDefinitionStoreException ex)
|
||||
{
|
||||
Assert.IsTrue( -1<ex.Message.IndexOf("already registered") );
|
||||
}
|
||||
|
||||
Assert.AreEqual(1, of.GetAliases("nAmE").Length);
|
||||
Assert.AreEqual(testObject, of.GetObject("nAmE"));
|
||||
Assert.AreEqual(testObject, of.GetObject("ALIAS"));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tests
|
||||
|
||||
/// <summary>
|
||||
/// Roderick objects inherits from rod, overriding name only.
|
||||
/// </summary>
|
||||
[Test]
|
||||
|
||||
@@ -69,9 +69,11 @@ namespace Spring.Objects.Factory.Xml
|
||||
|
||||
#endregion
|
||||
|
||||
protected internal override IObjectFactory ObjectFactory
|
||||
protected internal override AbstractObjectFactory CreateObjectFactory(bool caseSensitive)
|
||||
{
|
||||
get { return factory; }
|
||||
return (caseSensitive)
|
||||
? factory
|
||||
: new DefaultListableObjectFactory(caseSensitive);
|
||||
}
|
||||
|
||||
private DefaultListableObjectFactory parent;
|
||||
|
||||
@@ -252,6 +252,11 @@
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Collections\SynchronizedHashtableTests.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Context\ApplicationEventArgsTests.cs"
|
||||
SubType = "Code"
|
||||
|
||||
@@ -118,6 +118,7 @@
|
||||
<Compile Include="Collections\AbstractQueueTests.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Collections\CaseInsensitiveHashtableTests.cs" />
|
||||
<Compile Include="Collections\HashedSetTests.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
@@ -270,6 +271,7 @@
|
||||
<Compile Include="ExceptionsTest.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Expressions\ConstructorNodeTests.cs" />
|
||||
<Compile Include="Expressions\ExpressionEvaluatorTests.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
||||
@@ -140,6 +140,11 @@
|
||||
HintPath = "..\..\..\lib\Net\1.1\nunit.core.interfaces.dll"
|
||||
Private = "False"
|
||||
/>
|
||||
<Reference
|
||||
Name = "antlr.runtime"
|
||||
AssemblyName = "antlr.runtime"
|
||||
HintPath = "..\..\..\lib\Net\1.1\antlr.runtime.dll"
|
||||
/>
|
||||
</References>
|
||||
</Build>
|
||||
<Files>
|
||||
@@ -172,11 +177,24 @@
|
||||
RelPath = "Context\Support\HttpApplicationConfigurerTests.xml"
|
||||
BuildAction = "EmbeddedResource"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Context\Support\WebApplicationContextTests.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Core\IO\WebResourceTests.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Data\Spring\Context\Support\WebApplicationContextTests\Dummy.aspx"
|
||||
BuildAction = "Content"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Data\Spring\Context\Support\WebApplicationContextTests\Web.Config"
|
||||
BuildAction = "None"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Data\Spring\Objects\Factory\Support\TestForm.aspx"
|
||||
BuildAction = "Content"
|
||||
@@ -208,7 +226,7 @@
|
||||
BuildAction = "Content"
|
||||
/>
|
||||
<File
|
||||
RelPath = "Data\Spring\Web\Support\PageHandlerFactoryTests\Web.Config"
|
||||
RelPath = "Data\Spring\Web\Support\PageHandlerFactoryTests\Web.Config.net-1.1"
|
||||
BuildAction = "None"
|
||||
/>
|
||||
<File
|
||||
@@ -231,6 +249,11 @@
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "TestSupport\SessionMock.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "TestSupport\TestPage.cs"
|
||||
SubType = "ASPXCodeBehind"
|
||||
@@ -268,7 +291,7 @@
|
||||
/>
|
||||
<File
|
||||
RelPath = "Util\ControlInterceptionTests.cs"
|
||||
SubType = "Code"
|
||||
SubType = "ASPXCodeBehind"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="TestSupport\NUnitAdapter.cs" />
|
||||
<Compile Include="TestSupport\SessionMock.cs" />
|
||||
<Compile Include="TestSupport\TestPage.cs">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
|
||||
89
test/Spring/Spring.Web.Tests/TestSupport/SessionMock.cs
Normal file
89
test/Spring/Spring.Web.Tests/TestSupport/SessionMock.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Web;
|
||||
using System.Web.SessionState;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.TestSupport
|
||||
{
|
||||
/// <summary>
|
||||
/// Test Session implementation
|
||||
/// </summary>
|
||||
public class SessionMock : Hashtable, ISessionState
|
||||
{
|
||||
private bool _isCookieless;
|
||||
private bool _isNewSession;
|
||||
private int _lcid;
|
||||
private SessionStateMode _mode;
|
||||
private string _sessionID;
|
||||
private int _codePage;
|
||||
#if NET_2_0
|
||||
private HttpCookieMode _cookieMode;
|
||||
#endif
|
||||
public SessionMock() : base(CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
protected virtual void Reset()
|
||||
{
|
||||
_sessionID = Guid.NewGuid().ToString();
|
||||
_isNewSession = false;
|
||||
_isCookieless = false;
|
||||
_mode = SessionStateMode.InProc;
|
||||
_codePage = -1;
|
||||
#if NET_2_0
|
||||
_cookieMode = HttpCookieMode.AutoDetect;
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Abandon()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public bool IsCookieless
|
||||
{
|
||||
get { return _isCookieless; }
|
||||
set { _isCookieless = value; }
|
||||
}
|
||||
|
||||
public bool IsNewSession
|
||||
{
|
||||
get { return _isNewSession; }
|
||||
set { _isNewSession = value; }
|
||||
}
|
||||
|
||||
public int LCID
|
||||
{
|
||||
get { return _lcid; }
|
||||
set { _lcid = value; }
|
||||
}
|
||||
|
||||
public SessionStateMode Mode
|
||||
{
|
||||
get { return _mode; }
|
||||
set { _mode = value; }
|
||||
}
|
||||
|
||||
public string SessionID
|
||||
{
|
||||
get { return _sessionID; }
|
||||
set { _sessionID = value; }
|
||||
}
|
||||
|
||||
public int CodePage
|
||||
{
|
||||
get { return _codePage; }
|
||||
set { _codePage = value; }
|
||||
}
|
||||
|
||||
#if NET_2_0
|
||||
public HttpCookieMode CookieMode
|
||||
{
|
||||
get { return _cookieMode; }
|
||||
set { _cookieMode = value; }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
using Spring.Collections;
|
||||
using Page=Spring.Web.UI.Page;
|
||||
|
||||
namespace Spring.TestSupport
|
||||
@@ -13,7 +14,7 @@ namespace Spring.TestSupport
|
||||
{
|
||||
public TestPage()
|
||||
{
|
||||
this.SharedState = CollectionsUtil.CreateCaseInsensitiveHashtable();
|
||||
this.SharedState = new CaseInsensitiveHashtable(); //CollectionsUtil.CreateCaseInsensitiveHashtable();
|
||||
}
|
||||
|
||||
public TestPage( HttpContext context )
|
||||
|
||||
@@ -21,11 +21,16 @@
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using Spring.Collections;
|
||||
using Spring.Expressions;
|
||||
using Spring.Reflection.Dynamic;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -35,7 +40,8 @@ namespace Spring.TestSupport
|
||||
{
|
||||
private readonly TextWriter _out;
|
||||
private readonly HttpWorkerRequest _wr;
|
||||
[ThreadStatic] private static TestWebContext _wc;
|
||||
[ThreadStatic]
|
||||
private static TestWebContext _wc;
|
||||
|
||||
public static void Create(string virtualPath, string page)
|
||||
{
|
||||
@@ -54,24 +60,34 @@ namespace Spring.TestSupport
|
||||
{
|
||||
_out = new StringWriter();
|
||||
HttpWorkerRequest wr;
|
||||
object appPath = Thread.GetDomain().GetData(".appPath");
|
||||
AppDomain domain = Thread.GetDomain();
|
||||
|
||||
// are we running within a valid AspNet AppDomain?
|
||||
string appPath = (string) domain.GetData(".appPath");
|
||||
if (appPath != null)
|
||||
{
|
||||
wr = new SimpleWorkerRequest(page, string.Empty, _out);
|
||||
}
|
||||
else
|
||||
{
|
||||
string physDir = AppDomain.CurrentDomain.BaseDirectory + "\\";
|
||||
wr = new SimpleWorkerRequest(virtualPath, physDir, page, string.Empty, _out);
|
||||
appPath = domain.BaseDirectory + "\\";
|
||||
wr = new SimpleWorkerRequest(virtualPath, appPath, page, string.Empty, _out);
|
||||
}
|
||||
HttpContext ctx = new HttpContext(wr);
|
||||
HttpContext.Current = ctx;
|
||||
HttpBrowserCapabilities browser = new HttpBrowserCapabilities();
|
||||
#if NET_2_0
|
||||
browser.Capabilities = CollectionsUtil.CreateCaseInsensitiveHashtable();
|
||||
browser.Capabilities = new CaseInsensitiveHashtable(); //CollectionsUtil.CreateCaseInsensitiveHashtable();
|
||||
browser.Capabilities[string.Empty] = "Test User Agent"; // string.Empty is the key for "user agent"
|
||||
|
||||
// avoids NullReferenceException when accessing HttpRequest.FilePath
|
||||
object virtualPathObject = ExpressionEvaluator.GetValue(null, "T(System.Web.VirtualPath).Create('/')");
|
||||
object cachedPathData = ExpressionEvaluator.GetValue(null, "T(System.Web.CachedPathData).GetRootWebPathData()");
|
||||
ExpressionEvaluator.SetValue(cachedPathData, "_virtualPath", virtualPathObject);
|
||||
ExpressionEvaluator.SetValue(cachedPathData, "_physicalPath", appPath);
|
||||
#endif
|
||||
ctx.Request.Browser = browser;
|
||||
string filePath = ctx.Request.FilePath;
|
||||
_wr = wr;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using Spring.Collections;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.TestSupport
|
||||
@@ -8,7 +11,7 @@ namespace Spring.TestSupport
|
||||
/// Test environment implementation.
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
internal class VirtualEnvironmentMock : IVirtualEnvironment, IDisposable
|
||||
public class VirtualEnvironmentMock : IVirtualEnvironment, IDisposable
|
||||
{
|
||||
private readonly IVirtualEnvironment _prevEnvironment;
|
||||
|
||||
@@ -16,6 +19,8 @@ namespace Spring.TestSupport
|
||||
private readonly string _pathInfo;
|
||||
private string _currentExecutionFilePath;
|
||||
private readonly string _applicationVirtualPath;
|
||||
private ISessionState _session = new SessionMock();
|
||||
private IDictionary _requestVariables = new CaseInsensitiveHashtable(); //CollectionsUtil.CreateCaseInsensitiveHashtable();
|
||||
|
||||
public VirtualEnvironmentMock(string currentVirtualFilePath, string pathInfo, string applicationVirtualPath, bool autoInitialize)
|
||||
{
|
||||
@@ -63,6 +68,18 @@ namespace Spring.TestSupport
|
||||
return resultPath;
|
||||
}
|
||||
|
||||
public ISessionState Session
|
||||
{
|
||||
get { return _session; }
|
||||
set { _session = value; }
|
||||
}
|
||||
|
||||
public IDictionary RequestVariables
|
||||
{
|
||||
get { return _requestVariables; }
|
||||
set { _requestVariables = value; }
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
VirtualEnvironment.SetInstance(_prevEnvironment);
|
||||
|
||||
@@ -21,11 +21,15 @@
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.Data;
|
||||
using System.Web.UI.WebControls;
|
||||
using Common.Logging;
|
||||
using Common.Logging.Simple;
|
||||
using NUnit.Framework;
|
||||
using Spring.Context;
|
||||
using Spring.Context.Support;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.TestSupport;
|
||||
|
||||
#if NET_2_0
|
||||
@@ -86,20 +90,36 @@ namespace Spring.Util
|
||||
[Test, Explicit]
|
||||
public void RunTestWithDI()
|
||||
{
|
||||
// LogManager.Adapter = new Common.Logging.Simple.TraceLoggerFactoryAdapter();
|
||||
|
||||
DataView dv = CreateDataSource();
|
||||
IApplicationContext ctx = new StaticApplicationContext();
|
||||
|
||||
int runs = 1000;
|
||||
|
||||
StopWatch watch = new StopWatch();
|
||||
using (watch.Start("Duration: {0}"))
|
||||
using (TestWebContext wctx = new TestWebContext("/testpath", "testpage.aspx"))
|
||||
{
|
||||
for (int i = 0; i < runs; i++)
|
||||
IApplicationContext ctx = new WebApplicationContext();
|
||||
|
||||
int runs = 1000;
|
||||
|
||||
StopWatch watch = new StopWatch();
|
||||
using (watch.Start("Duration: {0}"))
|
||||
{
|
||||
DataGrid grid = new DataGrid();
|
||||
Spring.Web.Support.WebDependencyInjectionUtils.InjectDependenciesRecursive(ctx, grid);
|
||||
grid.DataSource = dv;
|
||||
grid.DataBind();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
DataGrid grid = new DataGrid();
|
||||
Spring.Web.Support.WebDependencyInjectionUtils.InjectDependenciesRecursive(ctx, grid);
|
||||
grid.DataSource = dv;
|
||||
grid.DataBind();
|
||||
}
|
||||
}
|
||||
|
||||
using (watch.Start("Duration: {0}"))
|
||||
{
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
DataGrid grid = new DataGrid();
|
||||
grid.DataSource = dv;
|
||||
grid.DataBind();
|
||||
Spring.Web.Support.WebDependencyInjectionUtils.InjectDependenciesRecursive(ctx, grid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,7 +132,7 @@ namespace Spring.Util
|
||||
Hashtable ht = new Hashtable();
|
||||
Dictionary<object, object> dict = new Dictionary<object, object>();
|
||||
|
||||
for(int i = 0; i < 100000; i++)
|
||||
for (int i = 0; i < 100000; i++)
|
||||
{
|
||||
ht.Add(i, new object());
|
||||
dict.Add(new object(), new object());
|
||||
|
||||
Reference in New Issue
Block a user