如何在调用IControllerFactory.GetControllerInstance()之前执行自定义代码?

时间:2012-01-25 20:17:00

标签: c# asp.net-mvc-3 structuremap

我需要在调用IControllerFactory.GetControllerInstance()之前执行一些自定义代码。

我已经查看了使用HtppApplication.BeginRequest事件,但这会执行我的代码对服务器发出的每个请求(包括对静态资源的请求) - 不理想。

我可以使用MVC中的扩展点来实现这一点吗?

2 个答案:

答案 0 :(得分:1)

我想不出你为什么需要这样做,但是,我认为最简单的方法是创建你自己的IControllerFactory。在MVC3中,还有新接口IControllerActivator

public interface IControllerActivator
{
    /// <summary>
    /// When implemented in a class, creates a controller.
    /// </summary>
    IController Create(RequestContext requestContext, Type controllerType);
}

以下是使用Unity的示例

public class UnityControllerFactory : DefaultControllerFactory
{
    /// <summary>
    /// 
    /// </summary>
    private readonly IUnityContainer _container;

    /// <summary>
    /// Initializes a new instance of the <see cref="UnityControllerFactory"/> class.
    /// </summary>
    /// <param name="container">The container.</param>
    /// <param name="controllerActivator">The controller activator.</param>
    public UnityControllerFactory(IUnityContainer container, IControllerActivator controllerActivator)
        : base(controllerActivator)
    {
        ////Guard.ArgumentNotNull(container, "container");
        _container = new PerRequestUnityContainer(container);
    }

    /// <summary>
    /// Releases the specified controller.
    /// </summary>
    /// <param name="controller">The controller to release.</param>
    public override void ReleaseController(IController controller)
    {
        if (controller != null)
        {
            _container.Teardown(controller);
        }

        base.ReleaseController(controller);
    }
}

public class UnityControllerActivator : IControllerActivator
{
    private readonly IUnityContainer _container;

    public UnityControllerActivator(IUnityContainer container)
    {
        ////Guard.ArgumentNotNull(container, "container");
        _container = new PerRequestUnityContainer(container);
    }

    /// <summary>
    /// When implemented in a class, creates a controller.
    /// </summary>
    /// <returns>
    /// The created controller.
    /// </returns>
    /// <param name="requestContext">The request context.</param><param name="controllerType">The controller type.</param>
    public IController Create(RequestContext requestContext, Type controllerType)
    {
        ////Guard.ArgumentNotNull(requestContext, "requestContext");
        ////Guard.ArgumentNotNull(controllerType, "controllerType");

        // do what ever you need to before creating your controller

        IController controller = (IController)_container.Resolve(controllerType);
        return controller;
    }
}

以及启动/启动捆绑过程中的某个地方,

IUnityContainer container = ...;

// resolve our factory (and any of it's dependencies)
IControllerFactory factory = container.Resolve<IControllerFactory>();
ControllerBuilder.Current.SetControllerFactory(factory);

答案 1 :(得分:1)

如果是我,我会通过自定义BaseController

运行代码
public class BaseController : System.Web.Mvc.Controller
{
    public BaseController()
    {
    }

    protected override System.Web.Mvc.IActionInvoker CreateActionInvoker()
    {
        // Call Custom Code Here

        return base.CreateActionInvoker();

    }
}

从那里,您可以随时从基本控制器继承。

public class MyController : MyApp.BaseController
{

}