Update of /cvsroot/springnet/Spring.Net/src/Spring/Spring.Web/Util
In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv17466/src/Spring/Spring.Web/Util
Modified Files:
ControlAccessor.cs ControlCollectionAccessor.cs
Log Message:
SPRNET-794 - complete rework of Control interception
minor fixes to SpringAir demo
switched DynamicField implementation to using net-2.0's DynamicMethod technique
Index: ControlAccessor.cs
===================================================================
RCS file: /cvsroot/springnet/Spring.Net/src/Spring/Spring.Web/Util/ControlAccessor.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** ControlAccessor.cs 27 Nov 2006 19:13:13 -0000 1.1
--- ControlAccessor.cs 13 May 2008 14:22:47 -0000 1.2
***************
*** 22,26 ****
--- 22,29 ----
using System.Diagnostics;
using System.Reflection;
+ using System.Reflection.Emit;
using System.Web.UI;
+ using Spring.Reflection.Dynamic;
+ using Spring.Web.Support;
#endregion
***************
*** 35,54 ****
internal class ControlAccessor
{
! private static readonly MethodInfo s_miCreateControlCollection =
! typeof (Control).GetMethod("CreateControlCollection", BindingFlags.Instance | BindingFlags.NonPublic);
! private static readonly MethodInfo s_miAddedControl =
! typeof (Control).GetMethod("AddedControl", BindingFlags.Instance | BindingFlags.NonPublic);
! private static readonly MethodInfo s_miRemovedControl =
! typeof (Control).GetMethod("RemovedControl", BindingFlags.Instance | BindingFlags.NonPublic);
! private static readonly MethodInfo s_miClear =
! typeof (ControlCollection).GetMethod("Clear", BindingFlags.Instance | BindingFlags.Public);
! private static readonly MethodInfo s_miClearNamingContainer =
! typeof (Control).GetMethod("ClearNamingContainer", BindingFlags.Instance | BindingFlags.NonPublic);
! private Control _targetControl;
/// <summary>
--- 38,123 ----
internal class ControlAccessor
{
! private static readonly MethodInfo s_miClear = GetMethod("Clear");
! private static MethodInfo GetMethod(string name)
! {
! return typeof(Control).GetMethod(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
! }
! private static FieldInfo GetField(string name)
! {
! return typeof(Control).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
! }
! private delegate ControlCollection CreateControlCollectionDelegate(Control target);
! private delegate void AddedControlDelegate(Control target, Control control, int index);
! private delegate void RemovedControlDelegate(Control target, Control control);
! private delegate void VoidMethodDelegate(Control target);
! #if NET_2_0
! private static readonly CreateControlCollectionDelegate BaseCreateControlCollection = (CreateControlCollectionDelegate) Delegate.CreateDelegate(typeof(CreateControlCollectionDelegate), GetMethod("CreateControlCollection"));
! private static readonly AddedControlDelegate BaseAddedControl = (AddedControlDelegate) Delegate.CreateDelegate(typeof (AddedControlDelegate), GetMethod("AddedControl"));
! private static readonly RemovedControlDelegate BaseRemovedControl = (RemovedControlDelegate) Delegate.CreateDelegate(typeof (RemovedControlDelegate), GetMethod("RemovedControl"));
! private static readonly VoidMethodDelegate BaseClearNamingContainer = (VoidMethodDelegate) Delegate.CreateDelegate(typeof (VoidMethodDelegate), GetMethod("ClearNamingContainer"));
! #else
! private class DynamicMethodWrapper
! {
! private IDynamicMethod _method;
! public DynamicMethodWrapper(IDynamicMethod method)
! {
! _method = method;
! }
! public static CreateControlCollectionDelegate CreateControlCollection(MethodInfo methodInfo)
! {
! IDynamicMethod method = new SafeMethod(methodInfo);
! return new CreateControlCollectionDelegate(new DynamicMethodWrapper(method).CreateControlCollectionInternal);
! }
! public static AddedControlDelegate AddedControl(MethodInfo methodInfo)
! {
! IDynamicMethod method = new SafeMethod(methodInfo);
! return new AddedControlDelegate(new DynamicMethodWrapper(method).AddedControlInternal);
! }
!
! public static RemovedControlDelegate RemovedControl(MethodInfo methodInfo)
! {
! IDynamicMethod method = new SafeMethod(methodInfo);
! return new RemovedControlDelegate(new DynamicMethodWrapper(method).RemovedControlInternal);
! }
!
! public static VoidMethodDelegate ClearNamingContainer(MethodInfo methodInfo)
! {
! IDynamicMethod method = new SafeMethod(methodInfo);
! return new VoidMethodDelegate(new DynamicMethodWrapper(method).ClearNamingContainerInternal);
! }
!
! private ControlCollection CreateControlCollectionInternal(Control target)
! {
! return (ControlCollection) _method.Invoke(target, null);
! }
!
! private void AddedControlInternal(Control target, Control control, int index)
! {
! _method.Invoke(target, new object[] { control, index });
! }
!
! private void RemovedControlInternal(Control target, Control control)
! {
! _method.Invoke(target, new object[] { control });
! }
!
! private void ClearNamingContainerInternal(Control target)
! {
! _method.Invoke(target, null);
! }
! }
!
! private static readonly CreateControlCollectionDelegate BaseCreateControlCollection = DynamicMethodWrapper.CreateControlCollection(GetMethod("CreateControlCollection"));
! private static readonly AddedControlDelegate BaseAddedControl = DynamicMethodWrapper.AddedControl(GetMethod("AddedControl"));
! private static readonly RemovedControlDelegate BaseRemovedControl = DynamicMethodWrapper.RemovedControl(GetMethod("RemovedControl"));
! private static readonly VoidMethodDelegate BaseClearNamingContainer = DynamicMethodWrapper.ClearNamingContainer(GetMethod("ClearNamingContainer"));
! #endif
!
! private readonly Control _targetControl;
/// <summary>
***************
*** 79,88 ****
get
{
! ControlCollection controls;
! controls = GetChildControlCollection();
if (controls == null)
{
! controls = CreateControlCollection();
! this.Controls = controls;
}
return controls;
--- 148,160 ----
get
{
! ControlCollection controls = GetChildControlCollection();
if (controls == null)
{
! controls = InterceptControlCollectionStrategy.TryCreateCollection(_targetControl);
! if (controls == null)
! {
! controls = BaseCreateControlCollection(_targetControl);
! }
! SetChildControlCollection(controls);
}
return controls;
***************
*** 91,111 ****
}
- /// <summary>
- /// Calls target's <see cref="Control.CreateControlCollection"/>
- /// </summary>
- /// <returns></returns>
- public ControlCollection CreateControlCollection()
- {
- return (ControlCollection) s_miCreateControlCollection.Invoke(this._targetControl, null);
- }
-
public void AddedControl(Control control, int index)
{
! s_miAddedControl.Invoke(_targetControl, new object[] {control, index});
}
public void RemovedControl(Control control)
{
! s_miRemovedControl.Invoke(_targetControl, new object[] {control});
if (!_targetControl.HasControls())
--- 163,174 ----
}
public void AddedControl(Control control, int index)
{
! BaseAddedControl(_targetControl, control, index);
}
public void RemovedControl(Control control)
{
! BaseRemovedControl(_targetControl, control);
if (!_targetControl.HasControls())
***************
*** 119,123 ****
if (_targetControl is INamingContainer)
{
! s_miClearNamingContainer.Invoke(_targetControl, null);
}
}
--- 182,187 ----
if (_targetControl is INamingContainer)
{
! //s_miClearNamingContainer.Invoke(_targetControl, null);
! BaseClearNamingContainer(_targetControl);
}
}
***************
*** 125,190 ****
}
! private ControlCollection GetChildControlCollection()
! {
! if (s_fiControls != null)
! {
! return GetChildControlCollection11();
! }
! else
! {
! return GetChildControlCollection20();
! }
! }
!
! private void SetChildControlCollection( ControlCollection controls )
! {
! if (s_fiControls != null)
! {
! SetChildControlCollection11(controls);
! }
! else
! {
! SetChildControlCollection20(controls);
! }
! }
!
! //#if NET_2_0
! private static readonly FieldInfo s_fiOccasionalFields = typeof(Control).GetField("_occasionalFields", BindingFlags.Instance | BindingFlags.NonPublic);
! private static readonly Type s_tOccasionalFields = typeof(Control).GetNestedType("OccasionalFields", BindingFlags.NonPublic);
! private static FieldInfo s_fiOccasionalFieldsControls = (s_tOccasionalFields == null) ? null : s_tOccasionalFields.GetField("Controls");
! private static MethodInfo s_miEnsureOccasionalFields = typeof(Control).GetMethod("EnsureOccasionalFields", BindingFlags.Instance | BindingFlags.NonPublic);
!
! private ControlCollection GetChildControlCollection20()
! {
! // we *must not* simply call control.Controls here!
! // Some controls (e.g. Repeater overload this property and call Control.EnsureChildControls()
! // which causes Control.ChildControlsCreated flag to be set and prevents children from being created after loading viewstate!
! s_miEnsureOccasionalFields.Invoke(_targetControl, null);
! object occasionalFields = s_fiOccasionalFields.GetValue(_targetControl);
! object childControls = s_fiOccasionalFieldsControls.GetValue(occasionalFields);
! return (ControlCollection) childControls;
! }
! private void SetChildControlCollection20( ControlCollection controls )
! {
! s_miEnsureOccasionalFields.Invoke(_targetControl, null);
! object occasionalFields = s_fiOccasionalFields.GetValue(_targetControl);
! s_fiOccasionalFieldsControls.SetValue(occasionalFields, controls);
! }
! //#else
! private static readonly FieldInfo s_fiControls =
! typeof (Control).GetField("_controls", BindingFlags.Instance | BindingFlags.NonPublic);
! private ControlCollection GetChildControlCollection11()
{
! if (s_fiControls == null) throw new ApplicationException("failed retrieving _controls field of " + typeof(Control).Assembly.FullName);
! return (ControlCollection) s_fiControls.GetValue(this._targetControl);
}
! private void SetChildControlCollection11(ControlCollection controls)
{
! s_fiControls.SetValue(this._targetControl, controls);
}
! //#endif
}
}
\ No newline at end of file
--- 189,301 ----
}
! #if NET_2_0
! private delegate ControlCollection GetControlsDelegate(Control target);
! private delegate void SetControlsDelegate(Control target, ControlCollection controls);
! private static readonly GetControlsDelegate GetChildControlCollectionInternal = GetGetControlsDelegate();
! private static readonly SetControlsDelegate SetChildControlCollectionInternal = GetSetControlsDelegate();
! private ControlCollection GetChildControlCollection()
! {
! return GetChildControlCollectionInternal(_targetControl);
! }
!
! private void SetChildControlCollection(ControlCollection controls)
! {
! SetChildControlCollectionInternal(_targetControl, controls);
! }
!
! private static GetControlsDelegate GetGetControlsDelegate()
! {
! FieldInfo occasionalFields = GetField("_occasionalFields");
! MethodInfo ensureOccasionalFields = GetMethod("EnsureOccasionalFields");
! FieldInfo controls = occasionalFields.FieldType.GetField("Controls");
!
! System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("get_Controls", typeof(ControlCollection), new Type[] { typeof(Control) }, typeof(Control).Module, true);
! ILGenerator il = dm.GetILGenerator();
! Label occFieldsNull = il.DefineLabel();
! Label retControls = il.DefineLabel();
! il.Emit(OpCodes.Ldarg_0);
! il.Emit(OpCodes.Ldfld, occasionalFields);
! il.Emit(OpCodes.Brfalse_S, occFieldsNull);
! il.MarkLabel(retControls);
! il.Emit(OpCodes.Ldarg_0);
! il.Emit(OpCodes.Ldfld, occasionalFields);
! il.Emit(OpCodes.Ldfld, controls);
! il.Emit(OpCodes.Ret);
! il.MarkLabel(occFieldsNull);
! il.Emit(OpCodes.Ldarg_0);
! il.Emit(OpCodes.Call, ensureOccasionalFields);
! il.Emit(OpCodes.Br, retControls);
!
! return (GetControlsDelegate) dm.CreateDelegate(typeof(GetControlsDelegate));
! }
!
! private static SetControlsDelegate GetSetControlsDelegate()
! {
! FieldInfo occasionalFields = GetField("_occasionalFields");
! MethodInfo ensureOccasionalFields = GetMethod("EnsureOccasionalFields");
! FieldInfo controls = occasionalFields.FieldType.GetField("Controls");
!
! System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("set_Controls", null, new Type[] { typeof(Control), typeof(ControlCollection) }, typeof(Control).Module, true);
! ILGenerator il = dm.GetILGenerator();
! Label occFieldsNull = il.DefineLabel();
! Label setControls = il.DefineLabel();
! il.Emit(OpCodes.Ldarg_0);
! il.Emit(OpCodes.Ldfld, occasionalFields);
! il.Emit(OpCodes.Brfalse_S, occFieldsNull);
! il.MarkLabel(setControls);
! il.Emit(OpCodes.Ldarg_0);
! il.Emit(OpCodes.Ldfld, occasionalFields);
! il.Emit(OpCodes.Ldarg_1);
! il.Emit(OpCodes.Stfld, controls);
! il.Emit(OpCodes.Ret);
! il.MarkLabel(occFieldsNull);
! il.Emit(OpCodes.Ldarg_0);
! il.Emit(OpCodes.Call, ensureOccasionalFields);
! il.Emit(OpCodes.Br, setControls);
!
! return (SetControlsDelegate) dm.CreateDelegate(typeof(SetControlsDelegate));
! }
!
! // private static readonly Type s_tOccasionalFields = typeof(Control).GetNestedType("OccasionalFields", BindingFlags.NonPublic);
! //
! // private static readonly VoidMethodDelegate EnsureOccasionalFields = (VoidMethodDelegate) Delegate.CreateDelegate(typeof (VoidMethodDelegate), GetMethod("EnsureOccasionalFields"));
! // private static readonly IDynamicField _occasionalFields = SafeField.CreateFrom(GetField("_occasionalFields"));
! // private static readonly IDynamicField _controls = SafeField.CreateFrom(s_tOccasionalFields.GetField("Controls"));
! //
! // private ControlCollection GetChildControlCollection()
! // {
! // // we *must not* simply call control.Controls here!
! // // Some controls (e.g. Repeater overload this property and call Control.EnsureChildControls()
! // // which causes Control.ChildControlsCreated flag to be set and prevents children from being created after loading viewstate!
! //
! // EnsureOccasionalFields(_targetControl);
! //
! // object occasionalFields = _occasionalFields.GetValue(_targetControl);
! // object childControls = _controls.GetValue(occasionalFields);
! // return (ControlCollection) childControls;
! // }
! //
! // private void SetChildControlCollection( ControlCollection controls )
! // {
! // EnsureOccasionalFields(_targetControl);
! //
! // object occasionalFields = _occasionalFields.GetValue(_targetControl);
! // _controls.SetValue(occasionalFields, controls);
! // }
! #else
! private static readonly IDynamicField fControls = SafeField.CreateFrom(GetField("_controls"));
!
! private ControlCollection GetChildControlCollection()
{
! return (ControlCollection)fControls.GetValue(_targetControl);
}
! private void SetChildControlCollection(ControlCollection controls)
{
! fControls.SetValue(_targetControl, controls);
}
! #endif
}
}
\ No newline at end of file
Index: ControlCollectionAccessor.cs
===================================================================
RCS file: /cvsroot/springnet/Spring.Net/src/Spring/Spring.Web/Util/ControlCollectionAccessor.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** ControlCollectionAccessor.cs 27 Nov 2006 19:13:13 -0000 1.1
--- ControlCollectionAccessor.cs 13 May 2008 14:22:47 -0000 1.2
***************
*** 19,24 ****
--- 19,26 ----
#region Imports
+ using System;
using System.Reflection;
using System.Web.UI;
+ using Spring.Reflection.Dynamic;
#endregion
***************
*** 33,40 ****
internal class ControlCollectionAccessor
{
! private static readonly FieldInfo s_fiOwner =
! typeof (ControlCollection).GetField("_owner", BindingFlags.Instance | BindingFlags.NonPublic);
!
! private ControlCollection _controls;
/// <summary>
--- 35,41 ----
internal class ControlCollectionAccessor
{
! private static readonly IDynamicField _owner = SafeField.CreateFrom(typeof (ControlCollection).GetField("_owner", BindingFlags.Instance | BindingFlags.NonPublic));
! private readonly ControlCollection _controls;
! private readonly Type _controlsType;
/// <summary>
***************
*** 47,50 ****
--- 48,59 ----
/// <summary>
+ /// Returns the type of the underlying ControlCollection instance.
+ /// </summary>
+ public Type GetTargetType()
+ {
+ return _controlsType;
+ }
+
+ /// <summary>
/// Creates a new Accessor for a given <see cref="ControlCollection"/>.
/// </summary>
***************
*** 53,56 ****
--- 62,66 ----
{
_controls = controls;
+ _controlsType = controls.GetType();
}
***************
*** 60,65 ****
public Control Owner
{
! get { return (Control) s_fiOwner.GetValue(_controls); }
! set { s_fiOwner.SetValue(_controls, value); }
}
}
--- 70,75 ----
public Control Owner
{
! get { return (Control) _owner.GetValue(_controls); }
! set { _owner.SetValue(_controls, value); }
}
}
|