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());
具有具体依赖关系的旧控制器代码:
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());