Skip to content

Commit

Permalink
SPRNET-1404
Browse files Browse the repository at this point in the history
Added ActionInvoker
  • Loading branch information
sbohlen committed Dec 10, 2010
1 parent 24aa39d commit a8d559a
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 49 deletions.
1 change: 1 addition & 0 deletions src/Spring/Spring.Web.Mvc/Spring.Web.Mvc.2010.csproj
Expand Up @@ -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>
Expand Down
84 changes: 84 additions & 0 deletions src/Spring/Spring.Web.Mvc/SpringActionInvoker.cs
@@ -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;
}

}

}
63 changes: 46 additions & 17 deletions src/Spring/Spring.Web.Mvc/SpringControllerFactory.cs
Expand Up @@ -61,8 +61,14 @@ public static IApplicationContext ApplicationContext
}
}



/// <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.
Expand All @@ -74,21 +80,21 @@ public static IApplicationContext ApplicationContext
/// <exception cref="T:System.ArgumentException">The <paramref name="controllerName"/> parameter is null or empty.</exception>
public override IController CreateController(RequestContext requestContext, string controllerName)
{
if (ApplicationContext.ContainsObjectDefinition(controllerName))
return ApplicationContext.GetObject(controllerName) as IController;
IController controller;

return base.CreateController(requestContext, controllerName);
}
if (ApplicationContext.ContainsObjectDefinition(controllerName))
{
controller = ApplicationContext.GetObject(controllerName) as IController;
}
else
{
controller = base.CreateController(requestContext, controllerName);
}

AddActionInvokerTo(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; }
return controller;
}

/// <summary>
/// Retrieves the controller instance for the specified request context and controller type.
Expand All @@ -103,17 +109,40 @@ public override IController CreateController(RequestContext requestContext, stri
/// <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);
}
}

}
Expand Down
66 changes: 34 additions & 32 deletions test/Spring/Spring.Web.Mvc.Tests/SpringControllerFactoryTests.cs
@@ -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
Expand Down Expand Up @@ -41,9 +41,11 @@ internal class MockContext : HttpContextBase { }
public class SpringControllerFactoryTests
{
private MvcApplicationContext _context;
private MvcApplicationContext _mvcNamedContext;

private SpringControllerFactory _factory;

private MvcApplicationContext _mvcNamedContext;

[SetUp]
public void _TestSetup()
{
Expand All @@ -65,16 +67,8 @@ public void _TestSetup()
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]
Expand All @@ -84,6 +78,11 @@ public void CanPreferIdMatchOverTypeMatch()
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()
Expand All @@ -98,14 +97,6 @@ public void CanRevertToTypeMatchIfIdMatchUnsuccessful()
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()
{
Expand All @@ -114,5 +105,16 @@ public void CanUseNamedContextToResolveController()

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());
}

}
}

0 comments on commit a8d559a

Please sign in to comment.