// This method could potentially return multiple selectors for the same controllerType due to
        // upgrading the lock from reader to writer, but the dictionary won't be corrupted as a result.
        public ActionMethodSelector GetSelector(Type controllerType)
        {
            ActionMethodSelector selector;

            _rwLock.AcquireReaderLock(Timeout.Infinite);
            try
            {
                if (_selectorDictionary.TryGetValue(controllerType, out selector))
                {
                    return selector;
                }
            }
            finally
            {
                _rwLock.ReleaseReaderLock();
            }

            // if we got this far, the selector was not in the cache
            selector = new ActionMethodSelector(controllerType);
            _rwLock.AcquireWriterLock(Timeout.Infinite);
            try
            {
                _selectorDictionary[controllerType] = selector;
                return selector;
            }
            finally
            {
                _rwLock.ReleaseWriterLock();
            }
        }
        // This method could potentially return multiple selectors for the same controllerType due to
        // upgrading the lock from reader to writer, but the dictionary won't be corrupted as a result.
        public ActionMethodSelector GetSelector(Type controllerType)
        {
            ActionMethodSelector selector;

            _rwLock.AcquireReaderLock(Timeout.Infinite);
            try {
                if (_selectorDictionary.TryGetValue(controllerType, out selector))
                {
                    return(selector);
                }
            }
            finally {
                _rwLock.ReleaseReaderLock();
            }

            // if we got this far, the selector was not in the cache
            selector = new ActionMethodSelector(controllerType);
            _rwLock.AcquireWriterLock(Timeout.Infinite);
            try {
                _selectorDictionary[controllerType] = selector;
                return(selector);
            }
            finally {
                _rwLock.ReleaseWriterLock();
            }
        }
        public ReflectedControllerDescriptor(Type controllerType) {
            if (controllerType == null) {
                throw new ArgumentNullException("controllerType");
            }

            _controllerType = controllerType;
            _selector = new ActionMethodSelector(_controllerType);
        }
        public void ControllerTypeProperty() {
            // Arrange
            Type controllerType = typeof(MethodLocatorController);
            ActionMethodSelector selector = new ActionMethodSelector(controllerType);

            // Act & Assert
            Assert.AreSame(controllerType, selector.ControllerType);
        }
        public ReflectedControllerDescriptor(Type controllerType)
        {
            if (controllerType == null)
            {
                throw new ArgumentNullException("controllerType");
            }

            _controllerType = controllerType;
            _selector       = new ActionMethodSelector(_controllerType);
        }
        public void FindActionMethodReturnsNullIfNoMethodMatches() {
            // Arrange
            Type controllerType = typeof(SelectionAttributeController);
            ActionMethodSelector selector = new ActionMethodSelector(controllerType);

            // Act
            MethodInfo matchedMethod = selector.FindActionMethod(null, "ZeroMatch");

            // Assert
            Assert.IsNull(matchedMethod, "No method should have matched.");
        }
        public void FindActionMethodReturnsMatchingMethodIfOneMethodMatches() {
            // Arrange
            Type controllerType = typeof(SelectionAttributeController);
            ActionMethodSelector selector = new ActionMethodSelector(controllerType);

            // Act
            MethodInfo matchedMethod = selector.FindActionMethod(null, "OneMatch");

            // Assert
            Assert.AreEqual("OneMatch", matchedMethod.Name, "Method named OneMatch() should have matched.");
            Assert.AreEqual(typeof(string), matchedMethod.GetParameters()[0].ParameterType, "Method overload OneMatch(string) should have matched.");
        }
        public void FindActionMethodThrowsIfMultipleMethodsMatch() {
            // Arrange
            Type controllerType = typeof(SelectionAttributeController);
            ActionMethodSelector selector = new ActionMethodSelector(controllerType);

            // Act & veriy
            ExceptionHelper.ExpectException<AmbiguousMatchException>(
                delegate {
                    selector.FindActionMethod(null, "TwoMatch");
                },
                @"The current request for action 'TwoMatch' on controller type 'SelectionAttributeController' is ambiguous between the following action methods:
Void TwoMatch2() on type System.Web.Mvc.Test.ActionMethodSelectorTest+SelectionAttributeController
Void TwoMatch() on type System.Web.Mvc.Test.ActionMethodSelectorTest+SelectionAttributeController");
        }
        public void FindActionMethodReturnsMethodWithActionSelectionAttributeIfMultipleMethodsMatchRequest() {
            // DevDiv Bugs 212062: If multiple action methods match a request, we should match only the methods with an
            // [ActionMethod] attribute since we assume those methods are more specific.

            // Arrange
            Type controllerType = typeof(SelectionAttributeController);
            ActionMethodSelector selector = new ActionMethodSelector(controllerType);

            // Act
            MethodInfo matchedMethod = selector.FindActionMethod(null, "ShouldMatchMethodWithSelectionAttribute");

            // Assert
            Assert.AreEqual("MethodHasSelectionAttribute1", matchedMethod.Name);
        }
        public void AliasedMethodsProperty() {
            // Arrange
            Type controllerType = typeof(MethodLocatorController);

            // Act
            ActionMethodSelector selector = new ActionMethodSelector(controllerType);

            // Assert
            Assert.AreEqual(2, selector.AliasedMethods.Length);

            List<MethodInfo> sortedAliasedMethods = selector.AliasedMethods.OrderBy(methodInfo => methodInfo.Name).ToList();
            Assert.AreEqual("Bar", sortedAliasedMethods[0].Name);
            Assert.AreEqual("FooRenamed", sortedAliasedMethods[1].Name);
        }
 public override ActionDescriptor FindAction(ControllerContext controllerContext, string actionName)
 {
     var selector = new ActionMethodSelector(controllerContext.Controller.GetType());
     var creator = selector.FindActionMethod(controllerContext, actionName);
     return creator == null ? null : creator(actionName, this);
 }
        public void NonAliasedMethodsProperty() {
            // Arrange
            Type controllerType = typeof(MethodLocatorController);

            // Act
            ActionMethodSelector selector = new ActionMethodSelector(controllerType);

            // Assert
            Assert.AreEqual(1, selector.NonAliasedMethods.Count);

            List<MethodInfo> sortedMethods = selector.NonAliasedMethods["foo"].OrderBy(methodInfo => methodInfo.GetParameters().Length).ToList();
            Assert.AreEqual("Foo", sortedMethods[0].Name);
            Assert.AreEqual(0, sortedMethods[0].GetParameters().Length);
            Assert.AreEqual("Foo", sortedMethods[1].Name);
            Assert.AreEqual(typeof(string), sortedMethods[1].GetParameters()[0].ParameterType);
        }