diff --git a/src/Spring/Spring.Web.Mvc/Spring.Web.Mvc.2010.csproj b/src/Spring/Spring.Web.Mvc/Spring.Web.Mvc.2010.csproj index 35d65ad91..f14e2a9e2 100644 --- a/src/Spring/Spring.Web.Mvc/Spring.Web.Mvc.2010.csproj +++ b/src/Spring/Spring.Web.Mvc/Spring.Web.Mvc.2010.csproj @@ -56,6 +56,7 @@ + diff --git a/src/Spring/Spring.Web.Mvc/SpringActionInvoker.cs b/src/Spring/Spring.Web.Mvc/SpringActionInvoker.cs new file mode 100644 index 000000000..8536619f6 --- /dev/null +++ b/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 +{ + /// + /// ActionInvoker implementation that enables the to satisfy dependencies on ActionFilter attributes. + /// + public class SpringActionInvoker : ControllerActionInvoker + { + private readonly IApplicationContext _context; + + /// + /// Initializes a new instance of the class. + /// + /// The IApplicationContext. + public SpringActionInvoker(IApplicationContext context) + { + _context = context; + } + + /// + /// Retrieves information about the action filters. + /// + /// The controller context. + /// The action descriptor. + /// Information about the action filters. + 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; + } + + } + +} diff --git a/src/Spring/Spring.Web.Mvc/SpringControllerFactory.cs b/src/Spring/Spring.Web.Mvc/SpringControllerFactory.cs index 1d63fdbe5..8e85fb8c8 100644 --- a/src/Spring/Spring.Web.Mvc/SpringControllerFactory.cs +++ b/src/Spring/Spring.Web.Mvc/SpringControllerFactory.cs @@ -61,8 +61,14 @@ public static IApplicationContext ApplicationContext } } - - + /// + /// Gets or sets the name of the application context. + /// + /// + /// Defaults to using the root (default) Application Context. + /// + /// The name of the application context. + public static string ApplicationContextName { get; set; } /// /// Creates the specified controller by using the specified request context. @@ -74,21 +80,21 @@ public static IApplicationContext ApplicationContext /// The parameter is null or empty. 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); - /// - /// Gets or sets the name of the application context. - /// - /// - /// Defaults to using the root (default) Application Context. - /// - /// The name of the application context. - public static string ApplicationContextName { get; set; } + return controller; + } /// /// Retrieves the controller instance for the specified request context and controller type. @@ -103,17 +109,40 @@ public override IController CreateController(RequestContext requestContext, stri /// An instance of cannot be created. 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().First().Value; + controller = (IController)controllers.Cast().First().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; + } + + /// + /// Adds the action invoker to the controller instance. + /// + /// The controller. + protected virtual void AddActionInvokerTo(IController controller) + { + if (controller == null) + return; + + if (typeof(Controller).IsAssignableFrom(controller.GetType())) + { + ((Controller)controller).ActionInvoker = new SpringActionInvoker(ApplicationContext); + } } } diff --git a/test/Spring/Spring.Web.Mvc.Tests/SpringControllerFactoryTests.cs b/test/Spring/Spring.Web.Mvc.Tests/SpringControllerFactoryTests.cs index 43cbac6a8..e42082db7 100644 --- a/test/Spring/Spring.Web.Mvc.Tests/SpringControllerFactoryTests.cs +++ b/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 @@ -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() { @@ -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] @@ -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() @@ -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() { @@ -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()); + } + } }