Unity如何在Unity

时间:2015-12-07 10:51:46

标签: asp.net-mvc dependency-injection inversion-of-control unity-container moq

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

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>();
       }
    }

1 个答案:

答案 0 :(得分:1)

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

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

你需要告诉MVC框架关于这个自定义控制器工厂(在Application_Start中):

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