Unity 如何在 Unity 的 Controller 构造函数中传递 Request

Unity how to pass Request in Controller's constructor from Unity

具有具体依赖关系的旧控制器代码:

public SomeController: Controller
{    
    public SomeController()
    {
    }

    public ActionResult Default()
    {
        **Something something = new Something(Request.ServerVariables["HTTP_X_REWRITE_URL"].ToString());**
        something.SomeMethod();
    }
}

以 TDD 为重点的新控制器代码:

public SomeControllerNew: Controller
{

    private readonly ISomething _something;

    public SomeControllerNew(ISomething something)
    {
        _something = something;
    }

    public ActionResult Default()
    {
        _something.SomeMethod();
    }
}

问题: 现在在新的 TDD 方法中,我需要在我注册接口的地方调用构造函数。我把它放在 UnityBootstraper 公共文件中,像这样: var container = new UnityContainer(); container.RegisterType();

**Something something = new Something(Request.ServerVariables["HTTP_X_REWRITE_URL"].ToString());**
        something.SomeMethod();

这在这里不起作用。错误很明显: 非静态字段、方法所需的对象引用,属性 'System.Web.Mvc.Controller.Request.get'.

我不知道如何在 UnityBootstrapper 中访问 http 请求?

编辑: 尝试在 RegisterRoutes 中完成所有这些操作。

 public class RouteConfig
    {        
       public static void RegisterRoutes(RouteCollection routes)
       {
              DependencyResolver.SetResolver(new Unity.Mvc3.UnityDependencyResolver(UnityBootstrapper.Initialise()));
              var container = new UnityContainer();
                container.RegisterType<ISometing, Something>();
       }
    }

一种方法是像这样创建一个抽象工厂:

public interface ISomethingFactory
{
    ISomething Create(string url);
}

public class SomethingFactory : ISomethingFactory
{
    public ISomething Create(string url)
    {
        return new Something(url);
    }
}

并让你的控制器像这样依赖它:

public class SomeControllerNew: Controller
{
    private readonly ISomething _something;

    public SomeControllerNew(ISomethingFactory somethingFactory)
    {
        _something = somethingFactory.Create(Request.ServerVariables["HTTP_X_REWRITE_URL"].ToString();
    }

    public ActionResult Default()
    {
        _something.SomeMethod();
    }
}

更好的方法 (IMO) 是使用自定义控制器工厂而不是像这样使用依赖项解析器:

public class CustomFactory : DefaultControllerFactory
{
    public override IController CreateController(RequestContext requestContext, string controllerName)
    {
        var request = requestContext.HttpContext.Request; //Here we have access to the request

        if (controllerName == "Some") //Name of controller
        {
            //Use the container to resolve and return the controller.
            //When you resolve, you can use ParameterOverride to specify the value of the string dependency that you need to inject into Something
        }

        return base.CreateController(requestContext, controllerName);
    }
}

这样你就不必引入 ISomethingFactory,你的控制器仍然直接依赖于 ISomething

您需要像这样(在 Application_Start 中)将此自定义控制器工厂告诉 MVC 框架:

ControllerBuilder.Current.SetControllerFactory(new CustomFactory());