我是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时不知道这一点。
我看了很多文章,论坛等,但似乎没有到达任何地方。
有人能指出我正确的方向吗?非常感谢您的帮助。
由于
答案 0 :(得分:0)
我知道你使用autofac但是在我们的项目中我们使用Unity,它肯定可以插入基本类型来进行类型注册:
container.RegisterTypeWithParams<INewsRepository, NewsRepository>("ConnectionString", typeof(ILoggedUser));
查看this
答案 1 :(得分:0)
一般情况下,您不希望这样做,因为您已对其进行了建模(您的PersonRepository)。 DI用于解决服务依赖性,您拥有的是有状态组件。
对此进行建模的方法是使用抽象工厂。马克·西曼对这个确切的主题有一个excellent blog post。
正如您在评论中指出的那样,通过方法注入传递值也是一种选择,但如果需要通过多个依赖项向下传递,则可能会很难看。