将构造函数参数传递给MVC控制器中的注入对象

时间:2013-06-09 12:41:18

标签: asp.net-mvc dependency-injection asp.net-web-api autofac

我正在使用.net开发MVC应用程序,我使用autofac作为IoC容器。

我的服务类需要构造函数中的参数。并且该参数在运行时从输入URL解析。

public interface IService {
 ...
}

public Service : IService {

 public Service(string input) {
 }
 ...

}

public class MyController : ApiController { 
    private IService _service;

    public MyController (IService service)
    {
        _service = service;
    }
}

我不确定在创建Service类时传递该参数的最佳方法是什么。处理这个问题的最佳做法是什么?

2 个答案:

答案 0 :(得分:4)

您有几种选择,通常取决于您希望与HttpContext的紧密联系。

第一个选项是使用lambda注册

builder.Register(c => new Service(HttpContext.Current.Request.RawUrl)).As<IService>();

这样做的好处是它简单易读。缺点是,当您重构Service类时,可能添加更多构造函数参数,您还必须重构您的注册。您也与HttpContext紧密相关,因此您在单元测试中使用此注册时会遇到问题。

第二个选项是您可以注册参数。您还希望注册AutofacWebTypesModule

// Automatically provides HttpRequestBase registration.
builder.RegisterModule<AutofacWebTypesModule>();
// Register the component using a parameter.
builder.RegisterType<Service>()
       .As<IService>()
       .WithParameter(
         // The first lambda determines which constructor parameter
         // will have the value provided.
         (p, c) => p.ParameterType == typeof(string),
         // The second lambda actually gets the value.
         (p, c) => {
           var request = c.Resolve<HttpRequestBase>();
           return request.RawUrl;
         });

这样做的好处是它将对象的实际构造与环境值的检索分开。您还可以通过添加存根HttpRequestBase值的测试注册来在单元测试中使用它。缺点是它需要更长的时间,并且可能比所需要的更复杂。

要么工作,它归结为你想要如何处理它。

答案 1 :(得分:0)

使用委托注册该服务:

builder.Register<IService>(container =>
{ 
    return new Service(HttpContext.Current.Request.RawUrl);
});