2

我正在使用 .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 类时传递该参数的最佳方式是什么。处理这个问题的最佳实践是什么?

4

2 回答 2

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值添加测试注册在单元测试中使用它。缺点是它有点长,可能感觉比要求的更复杂。

两者都可以,归结为您要如何处理它。

于 2013-06-10T16:23:05.337 回答
0

使用委托注册该服务:

builder.Register<IService>(container =>
{ 
    return new Service(HttpContext.Current.Request.RawUrl);
});
于 2013-06-09T21:36:08.330 回答