preparational changes for adding configurable control and response caching (SPRNET-972)
This commit is contained in:
@@ -187,6 +187,13 @@ namespace Spring.Util
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly SafeField ControlsArrayField = new SafeField(typeof(ControlCollection).GetField("_controls", BindingFlags.Instance|BindingFlags.NonPublic));
|
||||
public void SetControlAt(Control control, int index)
|
||||
{
|
||||
Control[] controls = (Control[]) ControlsArrayField.GetValue(this.Controls);
|
||||
controls[index] = control;
|
||||
}
|
||||
|
||||
#if NET_2_0
|
||||
private delegate ControlCollection GetControlsDelegate(Control target);
|
||||
private delegate void SetControlsDelegate(Control target, ControlCollection controls);
|
||||
@@ -297,4 +304,4 @@ namespace Spring.Util
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Web.UI;
|
||||
using Common.Logging;
|
||||
using Spring.Context;
|
||||
using Spring.Util;
|
||||
|
||||
@@ -33,6 +35,17 @@ namespace Spring.Web.Support
|
||||
/// <author>Erich Eichinger</author>
|
||||
internal sealed class ControlInterceptor
|
||||
{
|
||||
private class NoOpInterceptionStrategy : IInterceptionStrategy
|
||||
{
|
||||
private ILog Log = LogManager.GetLogger(typeof(NoOpInterceptionStrategy));
|
||||
|
||||
public bool Intercept(IApplicationContext defaultApplicationContext, ControlAccessor ctlAccessor,
|
||||
ControlCollectionAccessor ctlColAccessor)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds all available interception strategies
|
||||
/// </summary>
|
||||
@@ -41,7 +54,12 @@ namespace Spring.Web.Support
|
||||
new InterceptControlCollectionStrategy()
|
||||
, new InterceptControlCollectionOwnerStrategy()
|
||||
};
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The last resort interception strategy...
|
||||
/// </summary>
|
||||
private static readonly IInterceptionStrategy s_noopInterceptionStrategy = new NoOpInterceptionStrategy();
|
||||
|
||||
/// <summary>
|
||||
/// Holds a control.GetType()->IInterceptionStrategy table.
|
||||
/// </summary>
|
||||
@@ -102,12 +120,20 @@ namespace Spring.Web.Support
|
||||
else
|
||||
{
|
||||
// probe for a strategy
|
||||
bool bOk = false;
|
||||
for(int i=0;i<s_availableInterceptionStrategies.Length;i++)
|
||||
{
|
||||
bool bOk = s_availableInterceptionStrategies[i].Intercept(defaultApplicationContext, ctlAccessor, ctlColAccessor);
|
||||
strategy = s_availableInterceptionStrategies[i];
|
||||
bOk = strategy.Intercept(defaultApplicationContext, ctlAccessor, ctlColAccessor);
|
||||
if (bOk) break;
|
||||
}
|
||||
|
||||
if (!bOk)
|
||||
{
|
||||
LogManager.GetLogger(typeof(ControlInterceptor)).Warn(string.Format("dependency injection not supported for control type {0}", ctlAccessor.GetTarget().GetType()));
|
||||
strategy = s_noopInterceptionStrategy;
|
||||
}
|
||||
|
||||
lock(s_cachedInterceptionStrategies)
|
||||
{
|
||||
s_cachedInterceptionStrategies[control.GetType()] = strategy;
|
||||
@@ -130,4 +156,4 @@ namespace Spring.Web.Support
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Spring.Web.Support
|
||||
/// <summary>
|
||||
/// Holds a reference to the static(!) callback-method to be used during generation of intercepted ControlCollection-Types
|
||||
/// </summary>
|
||||
private delegate void InjectDependenciesCallbackHandler(IApplicationContext defaultApplicationContext, Control control);
|
||||
private delegate Control InjectDependenciesCallbackHandler(IApplicationContext defaultApplicationContext, Control control);
|
||||
|
||||
/// <summary>
|
||||
/// The list of methods to be intercepted for a ControlCollection
|
||||
@@ -216,4 +216,4 @@ namespace Spring.Web.Support
|
||||
return interceptedCollectionType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using Spring.Proxy;
|
||||
@@ -73,10 +74,19 @@ namespace Spring.Web.Support
|
||||
ParameterInfo[] callbackParams = _callbackMethod.GetParameters();
|
||||
ParameterInfo[] paramArray = method.GetParameters();
|
||||
|
||||
Type returnType = _callbackMethod.ReturnType;
|
||||
int replaceArgumentIndex = -1;
|
||||
|
||||
for (int j = 1; j < callbackParams.Length; j++)
|
||||
{
|
||||
for (int i = 0; i < paramArray.Length; i++)
|
||||
{
|
||||
// remember the parameter to assign the value returned from the callback to
|
||||
if (paramArray[i].ParameterType == returnType)
|
||||
{
|
||||
replaceArgumentIndex = i;
|
||||
}
|
||||
|
||||
if (paramArray[i].ParameterType == callbackParams[j].ParameterType)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_S, i + 1);
|
||||
@@ -87,7 +97,12 @@ namespace Spring.Web.Support
|
||||
|
||||
// invoke static(!) callback
|
||||
il.EmitCall(OpCodes.Call, _callbackMethod, null);
|
||||
// if callback has a result, store the result back into the first matching argument
|
||||
if (replaceArgumentIndex > -1)
|
||||
{
|
||||
il.Emit(OpCodes.Starg_S, (byte)replaceArgumentIndex+1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,8 +63,11 @@ namespace Spring.Web.Support
|
||||
protected override void AddedControl(Control control, int index)
|
||||
{
|
||||
// do DI
|
||||
WebDependencyInjectionUtils.InjectDependenciesRecursive(_defaultApplicationContext, control);
|
||||
|
||||
Control configuredControl = WebDependencyInjectionUtils.InjectDependenciesRecursive(_defaultApplicationContext, control);
|
||||
if (configuredControl != control)
|
||||
{
|
||||
_targetControl.SetControlAt( configuredControl, index );
|
||||
}
|
||||
_targetControl.AddedControl(control, index);
|
||||
}
|
||||
|
||||
@@ -77,4 +80,4 @@ namespace Spring.Web.Support
|
||||
_targetControl.RemovedControl(control);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,22 +36,23 @@ namespace Spring.Web.Support
|
||||
/// </summary>
|
||||
/// <param name="applicationContext">ApplicationContext to be used</param>
|
||||
/// <param name="control">Control to inject dependencies into.</param>
|
||||
public static void InjectDependenciesRecursive(IApplicationContext applicationContext, Control control)
|
||||
public static Control InjectDependenciesRecursive(IApplicationContext applicationContext, Control control)
|
||||
{
|
||||
if (applicationContext != null)
|
||||
{
|
||||
InjectDependenciesRecursiveInternal(applicationContext, control);
|
||||
control = InjectDependenciesRecursiveInternal(applicationContext, control);
|
||||
}
|
||||
return control;
|
||||
}
|
||||
|
||||
private static void InjectDependenciesRecursiveInternal(IApplicationContext appContext, Control control)
|
||||
private static Control InjectDependenciesRecursiveInternal(IApplicationContext appContext, Control control)
|
||||
{
|
||||
if (control is LiteralControl) return; // nothing to do
|
||||
if (control is LiteralControl) return control; // nothing to do
|
||||
|
||||
ISupportsWebDependencyInjection diControl = control as ISupportsWebDependencyInjection;
|
||||
if (diControl != null && diControl.DefaultApplicationContext != null)
|
||||
{
|
||||
return; // nothing to do anymore - control cares for its children
|
||||
return control; // nothing to do anymore - control cares for itself and its children
|
||||
}
|
||||
|
||||
// "intercept" Control to make it DI-aware
|
||||
@@ -72,7 +73,7 @@ namespace Spring.Web.Support
|
||||
}
|
||||
|
||||
// inject dependencies using control's context
|
||||
appContextToUse.ConfigureObject(control, control.GetType().FullName);
|
||||
control = (Control)appContextToUse.ConfigureObject(control, control.GetType().FullName);
|
||||
|
||||
// and now go for control's children
|
||||
if (control.HasControls())
|
||||
@@ -82,12 +83,18 @@ namespace Spring.Web.Support
|
||||
for (int i = 0; i < childCount; i++)
|
||||
{
|
||||
Control c = childControls[i];
|
||||
if (!(c is LiteralControl))
|
||||
if (c is LiteralControl) continue;
|
||||
|
||||
Control configuredControl = InjectDependenciesRecursiveInternal(appContext, c);
|
||||
if (configuredControl != c)
|
||||
{
|
||||
InjectDependenciesRecursiveInternal(appContext, c);
|
||||
ControlAccessor ac = new ControlAccessor(c.Parent);
|
||||
ac.SetControlAt(configuredControl, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return control;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -109,4 +116,4 @@ namespace Spring.Web.Support
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ namespace Spring.Web.UI.Controls
|
||||
if (!_suppressDependencyInjection
|
||||
&& _defaultApplicationContext != null)
|
||||
{
|
||||
WebDependencyInjectionUtils.InjectDependenciesRecursive(_defaultApplicationContext, control);
|
||||
control = WebDependencyInjectionUtils.InjectDependenciesRecursive(_defaultApplicationContext, control);
|
||||
}
|
||||
base.AddedControl(control, index);
|
||||
}
|
||||
@@ -187,4 +187,4 @@ namespace Spring.Web.UI.Controls
|
||||
|
||||
#endregion Dependency Injection Support
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,10 +178,10 @@ namespace Spring.Web.UI
|
||||
/// <returns>
|
||||
/// Returns the specified <see langword="UserControl"/> object, with dependencies injected.
|
||||
/// </returns>
|
||||
protected new Control LoadControl(string virtualPath)
|
||||
protected virtual new Control LoadControl(string virtualPath)
|
||||
{
|
||||
Control control = base.LoadControl(virtualPath);
|
||||
WebDependencyInjectionUtils.InjectDependenciesRecursive(defaultApplicationContext,control);
|
||||
control = WebDependencyInjectionUtils.InjectDependenciesRecursive(defaultApplicationContext,control);
|
||||
return control;
|
||||
}
|
||||
|
||||
@@ -194,10 +194,10 @@ namespace Spring.Web.UI
|
||||
/// <returns>
|
||||
/// Returns the specified <see langword="UserControl"/> object, with dependencies injected.
|
||||
/// </returns>
|
||||
protected new Control LoadControl( Type t, params object[] parameters)
|
||||
protected virtual new Control LoadControl( Type t, params object[] parameters)
|
||||
{
|
||||
Control control = base.LoadControl( t, parameters );
|
||||
WebDependencyInjectionUtils.InjectDependenciesRecursive(defaultApplicationContext,control);
|
||||
control = WebDependencyInjectionUtils.InjectDependenciesRecursive(defaultApplicationContext,control);
|
||||
return control;
|
||||
}
|
||||
|
||||
@@ -498,7 +498,7 @@ namespace Spring.Web.UI
|
||||
/// </summary>
|
||||
protected override void AddedControl(Control control,int index)
|
||||
{
|
||||
WebDependencyInjectionUtils.InjectDependenciesRecursive(defaultApplicationContext,control);
|
||||
control = WebDependencyInjectionUtils.InjectDependenciesRecursive(defaultApplicationContext,control);
|
||||
base.AddedControl(control,index);
|
||||
}
|
||||
|
||||
@@ -508,4 +508,4 @@ namespace Spring.Web.UI
|
||||
#endregion
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,10 +540,10 @@ namespace Spring.Web.UI
|
||||
/// <returns>
|
||||
/// Returns the specified <see langword="UserControl"/> object, with dependencies injected.
|
||||
/// </returns>
|
||||
protected new Control LoadControl(string virtualPath)
|
||||
protected virtual new Control LoadControl(string virtualPath)
|
||||
{
|
||||
Control control = base.LoadControl(virtualPath);
|
||||
WebDependencyInjectionUtils.InjectDependenciesRecursive(defaultApplicationContext, control);
|
||||
control = WebDependencyInjectionUtils.InjectDependenciesRecursive(defaultApplicationContext, control);
|
||||
return control;
|
||||
}
|
||||
|
||||
@@ -557,10 +557,10 @@ namespace Spring.Web.UI
|
||||
/// <returns>
|
||||
/// Returns the specified <see langword="UserControl"/> object, with dependencies injected.
|
||||
/// </returns>
|
||||
protected new Control LoadControl(Type t, params object[] parameters)
|
||||
protected virtual new Control LoadControl(Type t, params object[] parameters)
|
||||
{
|
||||
Control control = base.LoadControl(t, parameters);
|
||||
WebDependencyInjectionUtils.InjectDependenciesRecursive(defaultApplicationContext, control);
|
||||
control = WebDependencyInjectionUtils.InjectDependenciesRecursive(defaultApplicationContext, control);
|
||||
return control;
|
||||
}
|
||||
#endif
|
||||
@@ -1656,11 +1656,11 @@ namespace Spring.Web.UI
|
||||
/// </summary>
|
||||
protected override void AddedControl(Control control, int index)
|
||||
{
|
||||
WebDependencyInjectionUtils.InjectDependenciesRecursive(defaultApplicationContext, control);
|
||||
control = WebDependencyInjectionUtils.InjectDependenciesRecursive(defaultApplicationContext, control);
|
||||
base.AddedControl(control, index);
|
||||
}
|
||||
|
||||
#endregion Dependency Injection Support
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,10 +280,10 @@ namespace Spring.Web.UI
|
||||
/// <returns>
|
||||
/// Returns the specified <see langword="UserControl"/> object, with dependencies injected.
|
||||
/// </returns>
|
||||
protected new Control LoadControl(string virtualPath)
|
||||
protected virtual new Control LoadControl(string virtualPath)
|
||||
{
|
||||
Control control = base.LoadControl(virtualPath);
|
||||
WebDependencyInjectionUtils.InjectDependenciesRecursive(defaultApplicationContext, control);
|
||||
control = WebDependencyInjectionUtils.InjectDependenciesRecursive(defaultApplicationContext, control);
|
||||
return control;
|
||||
}
|
||||
|
||||
@@ -297,10 +297,10 @@ namespace Spring.Web.UI
|
||||
/// <returns>
|
||||
/// Returns the specified <see langword="UserControl"/> object, with dependencies injected.
|
||||
/// </returns>
|
||||
protected new Control LoadControl( Type t, params object[] parameters)
|
||||
protected virtual new Control LoadControl( Type t, params object[] parameters)
|
||||
{
|
||||
Control control = base.LoadControl( t, parameters );
|
||||
WebDependencyInjectionUtils.InjectDependenciesRecursive(defaultApplicationContext, control);
|
||||
control = WebDependencyInjectionUtils.InjectDependenciesRecursive(defaultApplicationContext, control);
|
||||
return control;
|
||||
}
|
||||
#endif
|
||||
@@ -1062,4 +1062,4 @@ namespace Spring.Web.UI
|
||||
|
||||
#endregion Dependency Injection Support
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,4 +292,35 @@ namespace Spring.Util
|
||||
}
|
||||
|
||||
#endregion Test Support Classes
|
||||
}
|
||||
|
||||
#region DI Templates // look at them using reflector
|
||||
|
||||
internal class DIControlCollection : ControlCollection, ISupportsWebDependencyInjection
|
||||
{
|
||||
private IApplicationContext _defaultApplicationContext;
|
||||
|
||||
public DIControlCollection(Control owner) : base(owner)
|
||||
{
|
||||
}
|
||||
|
||||
IApplicationContext ISupportsWebDependencyInjection.DefaultApplicationContext
|
||||
{
|
||||
get { return _defaultApplicationContext; }
|
||||
set { _defaultApplicationContext = value; }
|
||||
}
|
||||
|
||||
public override void Add(Control child)
|
||||
{
|
||||
child = WebDependencyInjectionUtils.InjectDependenciesRecursive(_defaultApplicationContext, child);
|
||||
base.Add(child);
|
||||
}
|
||||
|
||||
public override void AddAt(int index, Control child)
|
||||
{
|
||||
child = WebDependencyInjectionUtils.InjectDependenciesRecursive(_defaultApplicationContext, child);
|
||||
base.AddAt(index, child);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user