SPRNET-1404

Added ActionInvoker
This commit is contained in:
sbohlen
2010-12-10 19:05:03 +00:00
parent 24aa39de10
commit a8d559a426
4 changed files with 165 additions and 49 deletions

View File

@@ -56,6 +56,7 @@
<Compile Include="Context\Support\MvcApplicationContext.cs" />
<Compile Include="Context\Support\MvcApplicationContextArgs.cs" />
<Compile Include="Context\Support\MvcContextHandler.cs" />
<Compile Include="SpringActionInvoker.cs" />
<Compile Include="SpringControllerFactory.cs" />
<Compile Include="SpringMvcApplication.cs" />
</ItemGroup>

View File

@@ -0,0 +1,84 @@
#region License
/*
* Copyright © 2002-2010 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.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Spring.Context;
using Spring.Context.Support;
namespace Spring.Web.Mvc
{
/// <summary>
/// ActionInvoker implementation that enables the <see cref="IApplicationContext"/>to satisfy dependencies on ActionFilter attributes.
/// </summary>
public class SpringActionInvoker : ControllerActionInvoker
{
private readonly IApplicationContext _context;
/// <summary>
/// Initializes a new instance of the <see cref="SpringActionInvoker"/> class.
/// </summary>
/// <param name="context">The IApplicationContext.</param>
public SpringActionInvoker(IApplicationContext context)
{
_context = context;
}
/// <summary>
/// Retrieves information about the action filters.
/// </summary>
/// <param name="controllerContext">The controller context.</param>
/// <param name="actionDescriptor">The action descriptor.</param>
/// <returns>Information about the action filters.</returns>
protected override FilterInfo GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
//let the base class do the actual work as usual
var filterInfo = base.GetFilters(controllerContext, actionDescriptor);
//configure each collection of filters using the IApplicationContext
foreach (IActionFilter filter in filterInfo.ActionFilters.Where(f => f != null))
{
_context.ConfigureObject(filter, filter.GetType().FullName);
}
foreach (IAuthorizationFilter filter in filterInfo.AuthorizationFilters.Where(f => f != null))
{
_context.ConfigureObject(filter, filter.GetType().FullName);
}
foreach (IExceptionFilter filter in filterInfo.ExceptionFilters.Where(f => f != null))
{
_context.ConfigureObject(filter, filter.GetType().FullName);
}
foreach (IResultFilter filter in filterInfo.ResultFilters.Where(f => f != null))
{
_context.ConfigureObject(filter, filter.GetType().FullName);
}
return filterInfo;
}
}
}

View File

@@ -61,8 +61,14 @@ namespace Spring.Web.Mvc
}
}
/// <summary>
/// Gets or sets the name of the application context.
/// </summary>
/// <remarks>
/// Defaults to using the root (default) Application Context.
/// </remarks>
/// <value>The name of the application context.</value>
public static string ApplicationContextName { get; set; }
/// <summary>
/// Creates the specified controller by using the specified request context.
@@ -74,22 +80,22 @@ namespace Spring.Web.Mvc
/// <exception cref="T:System.ArgumentException">The <paramref name="controllerName"/> parameter is null or empty.</exception>
public override IController CreateController(RequestContext requestContext, string controllerName)
{
IController controller;
if (ApplicationContext.ContainsObjectDefinition(controllerName))
return ApplicationContext.GetObject(controllerName) as IController;
{
controller = ApplicationContext.GetObject(controllerName) as IController;
}
else
{
controller = base.CreateController(requestContext, controllerName);
}
return base.CreateController(requestContext, controllerName);
AddActionInvokerTo(controller);
return controller;
}
/// <summary>
/// Gets or sets the name of the application context.
/// </summary>
/// <remarks>
/// Defaults to using the root (default) Application Context.
/// </remarks>
/// <value>The name of the application context.</value>
public static string ApplicationContextName { get; set; }
/// <summary>
/// Retrieves the controller instance for the specified request context and controller type.
/// </summary>
@@ -103,17 +109,40 @@ namespace Spring.Web.Mvc
/// <exception cref="T:System.InvalidOperationException">An instance of <paramref name="controllerType"/> cannot be created.</exception>
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
IController controller = null;
if (controllerType != null)
{
var controllers = ApplicationContext.GetObjectsOfType(controllerType);
if (controllers.Count > 0)
{
return (IController)controllers.Cast<DictionaryEntry>().First<DictionaryEntry>().Value;
controller = (IController)controllers.Cast<DictionaryEntry>().First<DictionaryEntry>().Value;
}
}
else
{
//pass to base class for remainder of handling if can't find it in the context
controller = base.GetControllerInstance(requestContext, controllerType);
}
//pass to base class for remainder of handling if can't find it in the context
return base.GetControllerInstance(requestContext, controllerType);
AddActionInvokerTo(controller);
return controller;
}
/// <summary>
/// Adds the action invoker to the controller instance.
/// </summary>
/// <param name="controller">The controller.</param>
protected virtual void AddActionInvokerTo(IController controller)
{
if (controller == null)
return;
if (typeof(Controller).IsAssignableFrom(controller.GetType()))
{
((Controller)controller).ActionInvoker = new SpringActionInvoker(ApplicationContext);
}
}
}

View File

@@ -1,19 +1,19 @@
#region License
/*
* Copyright © 2002-2010 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.
/*
* Copyright © 2002-2010 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
@@ -41,9 +41,11 @@ namespace Spring.Web.Mvc.Tests
public class SpringControllerFactoryTests
{
private MvcApplicationContext _context;
private MvcApplicationContext _mvcNamedContext;
private SpringControllerFactory _factory;
private MvcApplicationContext _mvcNamedContext;
[SetUp]
public void _TestSetup()
{
@@ -65,16 +67,8 @@ namespace Spring.Web.Mvc.Tests
typeof(NotInContainerController),
typeof(NamedContextController),
});
}
[Test]
public void ProperlyResolvesCaseInsensitiveControllerNames()
{
IController pascalcaseController = _factory.CreateController(new RequestContext(new MockContext(), new RouteData()), "FirstContainerRegistered");
IController lowercaseController = _factory.CreateController(new RequestContext(new MockContext(), new RouteData()), "firstcontainerregistered");
Assert.AreEqual(typeof(FirstContainerRegisteredController), pascalcaseController.GetType());
Assert.AreEqual(typeof(FirstContainerRegisteredController), lowercaseController.GetType());
SpringControllerFactory.ApplicationContextName = string.Empty;
}
[Test]
@@ -84,6 +78,11 @@ namespace Spring.Web.Mvc.Tests
Assert.AreEqual("Should_Be_Matched_By_Id", ((FirstContainerRegisteredController)controller).TestValue);
}
[Test]
public void CanRetrieveControllersNotRegisteredWithContainer()
{
_factory.CreateController(new RequestContext(new MockContext(), new RouteData()), "NotInContainer");
}
[Test]
public void CanRevertToTypeMatchIfIdMatchUnsuccessful()
@@ -98,14 +97,6 @@ namespace Spring.Web.Mvc.Tests
Assert.AreEqual("Should_Be_Matched_By_Type", ((FirstContainerRegisteredController)controller).TestValue);
}
[Test]
public void CanRetrieveControllersNotRegisteredWithContainer()
{
_factory.CreateController(new RequestContext(new MockContext(), new RouteData()), "NotInContainer");
}
[Test]
public void CanUseNamedContextToResolveController()
{
@@ -114,5 +105,16 @@ namespace Spring.Web.Mvc.Tests
Assert.NotNull(controller);
}
[Test]
public void ProperlyResolvesCaseInsensitiveControllerNames()
{
IController pascalcaseController = _factory.CreateController(new RequestContext(new MockContext(), new RouteData()), "FirstContainerRegistered");
IController lowercaseController = _factory.CreateController(new RequestContext(new MockContext(), new RouteData()), "firstcontainerregistered");
Assert.AreEqual(typeof(FirstContainerRegisteredController), pascalcaseController.GetType());
Assert.AreEqual(typeof(FirstContainerRegisteredController), lowercaseController.GetType());
}
}
}