使用Autofac的ASP.Net MVC构造函数注入 - 运行时参数

时间:2014-07-18 15:27:10

标签: c# asp.net asp.net-mvc dependency-injection autofac

我是Autofac的新手,并且在注入具有仅在运行时已知的参数的依赖项时遇到了问题。 (下面的代码是我试图描述的问题的一个例子。)

这是我设置容器的地方(在Global.asax中调用)

public class Bootstrapper
{
    public static void Config()
    {
        var builder = new ContainerBuilder();
        builder.RegisterControllers(Assembly.GetExecutingAssembly());

        builder.RegisterType<PersonService>().As<IPersonService>().InstancePerHttpRequest();
        builder.RegisterType<PersonRepository>().As<IPersonRepository>().InstancePerHttpRequest();

        IContainer container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    }
}

以下是类型。

public class PersonService : IPersonService
{
    private readonly IPersonRepository _repository;

    public PersonService(IPersonRepository repository)
    {
        _repository = repository;
    }

    public Person GetPerson(int id)
    {
        return _repository.GetPerson(id);
    }
}

public interface IPersonRepository
{
    Person GetPerson(int id);
}

public class PersonRepository : IPersonRepository
{
    private readonly int _serviceId;

    public PersonRepository(int serviceId)
    {
        _serviceId = serviceId;
    }

    public Person GetPerson(int id)
    {
        throw new System.NotImplementedException();
    }
}

然后控制器在构造函数中获取PersonService

 public class HomeController : Controller
{
    private readonly IPersonService _service;

    public HomeController(IPersonService service)
    {
        _service = service;
    }

    public ActionResult Index()
    {
        return View();
    }

}

显然,由于容器期望PersonRepository的构造函数上的ServiceId参数具有以下异常“无法解析参数'Int32 serviceId'”,这将会失败。

一旦我知道HttpContext.Request.Current.Url,我就可以获得serviceId,但是在创建Container时不知道这一点。

我看了很多文章,论坛等,但似乎没有到达任何地方。

有人能指出我正确的方向吗?非常感谢您的帮助。

由于

2 个答案:

答案 0 :(得分:0)

我知道你使用autofac但是在我们的项目中我们使用Unity,它肯定可以插入基本类型来进行类型注册:

container.RegisterTypeWithParams<INewsRepository, NewsRepository>("ConnectionString", typeof(ILoggedUser));

查看this

答案 1 :(得分:0)

一般情况下,您不希望这样做,因为您已对其进行了建模(您的PersonRepository)。 DI用于解决服务依赖性,您拥有的是有状态组件。

对此进行建模的方法是使用抽象工厂。马克·西曼对这个确切的主题有一个excellent blog post

正如您在评论中指出的那样,通过方法注入传递值也是一种选择,但如果需要通过多个依赖项向下传递,则可能会很难看。