0

我偶然发现了这种方法

protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
        {
            throw new HttpException(404,
                                    String.Format(
                                        CultureInfo.CurrentCulture,
                                        MvcResources.DefaultControllerFactory_NoControllerFound,
                                        requestContext.HttpContext.Request.Path));
        }
        if (!typeof(IController).IsAssignableFrom(controllerType))
        {
            throw new ArgumentException(
                String.Format(
                    CultureInfo.CurrentCulture,
                    MvcResources.DefaultControllerFactory_TypeDoesNotSubclassControllerBase,
                    controllerType),
                "controllerType");
        }
        return ControllerActivator.Create(requestContext, controllerType);
    }

我想知道 requestContext 参数的用途是什么,因为它似乎从未使用过。它被传递给 ControllerActivator.Create 但它也从未真正在那里使用过:

public IController Create(RequestContext requestContext, Type controllerType)
        {
            try
            {
                return (IController)(_resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType));
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException(
                    String.Format(
                        CultureInfo.CurrentCulture,
                        MvcResources.DefaultControllerFactory_ErrorCreatingController,
                        controllerType),
                    ex);
            }
        }
4

1 回答 1

0

的目的是按需ControllerFactory创建实例。Controller为了能够确定适当的Controller类型,它可能需要 RequestContext 数据。

现在,DefaultControllerFactory(这是默认工厂)确实使用RequestContextonly 来抛出Http 404 Not Found异常(在需要时),但其他控制器工厂(必须实现IControllerFactory)可能会使用它。

例如,UnityControllerFactory来源):

public class UnityControllerFactory : DefaultControllerFactory
    {
        public override IController CreateController(RequestContext context, string controllerName)
        {
            Type type = GetControllerType(context, controllerName);

            if (type == null)
            {
                throw new InvalidOperationException(string.Format("Could not find a controller with the name {0}", controllerName));
            }

            IUnityContainer container = GetContainer(context);
            return (IController)container.Resolve(type);
        }

        protected virtual IUnityContainer GetContainer(RequestContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            var unityContainerAccessor = context.HttpContext.ApplicationInstance as IUnityContainerAccessor;
            if (unityContainerAccessor == null)
            {
                throw new InvalidOperationException(
                    "You must extend the HttpApplication in your web project and implement the IContainerAccessor to properly expose your container instance");
            }

            IUnityContainer container = unityContainerAccessor.Container;
            if (container == null)
            {
                throw new InvalidOperationException("The container seems to be unavailable in your HttpApplication subclass");
            }

            return container;
        }
于 2013-09-03T08:58:59.940 回答