【发布时间】:2013-12-19 19:18:47
【问题描述】:
我已经在 MVC 中设置了 Castle Windsor IoC。我已经阅读了教程,并做到了这一点:
public class HomeController : Controller
{
/////////////////////////////////////////////////////////////
// Attributes
public ISearchService SearchService { get; set; }
public IFeedbackService FeedbackService { get; set; }
HomeController 负责处理搜索和存储反馈,因此 HomeController 有两个由 IoC 创建的服务引用。
这不是我真正想要的。我不想为 Home 控制器上的每个请求构建两个服务,因为大多数时候不需要它们。当我确定需要它们时,我想在动作函数中构造它们。
以前,我使用 Microsoft Unity,我的操作函数中有很多 ServiceLocator.Resolve<thing>()。当涉及到测试时,这是一个真正的痛苦,我已经读过它是不可取的(并且是反模式)。
我的愿望是:
[HttpPost]
public ActionResult(FeedbackViewModel vm,IFeedbackService feedbackService)
{
并让 IoC 构造第二个参数而不是第一个参数。这可能吗?
如果没有,我将不得不找到一种方法来创建服务构造函数的成员,而不使用静态引用。
感谢阅读。
使用 Brent Mannering 的回答更新:
我尝试创建 ResolveThis 参数,但无法检查 BindModel 函数中的属性。所以我坚持解决所有接口:
/// <summary>
///
/// </summary>
public class DependencyModelBinder : DefaultModelBinder
{
/////////////////////////////////////////////////////////////
// Attributes
private IKernel _kernel;
/////////////////////////////////////////////////////////////
// Construction
public DependencyModelBinder(IKernel kernel)
{
// Initialize member variables
_kernel = kernel;
}
/////////////////////////////////////////////////////////////
// Implementation
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
// If this is an interface...
if(bindingContext.ModelType.IsInterface)
{
// Resolve the object and return
return _kernel.Resolve(bindingContext.ModelType);
}
// Call base-class function
return base.BindModel(controllerContext, bindingContext);
}
}
【问题讨论】:
-
我建议您只使用普通的旧 DI 并将服务注入控制器的构造函数。
-
感谢 Maess,但这意味着构建两个服务,以及与它们一起使用的所有存储库类,但它们可能不会被使用。这不是可耻的低效吗?
-
梅斯是对的。您应该使用构造函数注入,因为 Castle Windsor 中的属性是可选的。如果您忘记注册其中一个依赖项,控制器仍然可以创建,但该属性将为空。这将在稍后导致 NullReferenceException。最好让应用程序失败 a.s.a.p。这意味着您应该使用构造函数注入。
-
另外,你有没有测试过性能差异是什么?构建依赖图通常是very fast(即使使用像 Castle 这样的框架),尤其是与 Web 框架的开销相比。如果您注入仅在部分时间使用的依赖项,它不应该有任何明显的区别。如果其中一个依赖项需要很长时间才能创建,则意味着该依赖项的构造函数做得太多,应该重构这个类。
标签: asp.net-mvc model-view-controller inversion-of-control castle-windsor