我正在使用.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类时传递该参数的最佳方法是什么。处理这个问题的最佳做法是什么?
答案 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);
});