【问题标题】:Dynamically injecting constructor parameters using Unity使用 Unity 动态注入构造函数参数
【发布时间】:2012-10-09 09:51:47
【问题描述】:
我在 ASP.NET MVC 4 应用程序中使用 Unity 容器进行依赖注入。
对于一个特定的控制器(比如 ProductController),我有一个依赖注入场景如下:
- ProductController 构造函数采用 IProductsRepository 实例。
- IProductsRepository 实现有一个接受 IProductsService 实例的构造函数。
- IProductsService 实现有一个接受身份验证令牌字符串的构造函数,该字符串是从 Web 请求中的 cookie 中检索的。
考虑到身份验证令牌cookie只能在控制器实例创建后才能检索到,在这种情况下进行自动依赖注入的正确方法是什么?
【问题讨论】:
标签:
asp.net-mvc
dependency-injection
unity-container
constructor-injection
【解决方案1】:
如果您需要延迟创建ProductService,您可以
- 为该服务注入自定义工厂
- 让 DI 容器自动生成
Func<IProductService> 类型的委托工厂并将该委托注入到您的控制器中
- 让容器生成一个lazy proxy,向消费者隐藏服务的延迟创建
我更喜欢第三种选择,因为它对IProductService 的消费者完全透明
【解决方案2】:
我认为你有两个选择:
1 使用 container.Resolve() 并在可用时传递参数。
因此,与其在 ProductsRepository 的构造函数中请求 IProductsService,不如执行以下操作:
IProductsService anInstance = container.Resolve<IProductsService>(new ParameterOverride("authenticationTokenString", "myValue"));
这称为 ParameterOverride。 MSDN 文档可以在这里找到:Resolving Objects by Using Overrides
2 不要传递普通的身份验证令牌字符串,而是将其封装在一个接口后面并传递那个。您的 IProductsService 将采用 IAuthenticationTokenProvider 并要求该班级提供所需的令牌。您的实现将在创建所需的对象后访问它们以获取正确的值。
我会选择选项二。它将使您的设计更简洁,让 Unity 处理所有依赖注入,而无需任何手动工作。