ASP.NET MVC3依赖注入误解

时间:2011-05-05 15:11:36

标签: asp.net-mvc asp.net-mvc-3 dependency-injection unity-container

public object GetService(Type serviceType)
{
    object resolvedObject = null;
    try
    {
        resolvedObject = _unityContainer.Resolve(serviceType);
    }
    catch(ResolutionFailedException e) { }

    return resolvedObject;
}

这是捕获异常并返回null的最佳做法吗?默认情况下,mvc尝试解析IControllerFactory和IViewPageActivator,即我得到两个catched异常。我不喜欢这个解决方案。

我的朋友建议检查IControllerFactoryIViewPageActivator上的serviceType,如果出现异常,请抓住并记录错误。但就我而言 - 它不是最好的解决方案,它就像硬编码一样。

3 个答案:

答案 0 :(得分:5)

MVC3的DependencyResolver是服务定位器,首先是。它本质上是MVC和公共服务定位器(commonservicelocator.codeplex.com)的爱心。 CSL服务定位器和MVC3的DependencyResolver之间的区别在于MVC架构师决定他们需要一种更安全的方式来处理无法通过它解决服务的情况,他们选择的答案是{{1在这些情况下应该返回null。

使用IServiceLocator的CSL实现,标准做法是抛出IDependencyResolver,允许处理这些情况的标准化异常。

使用MVC,框架将调用ActivationException来尝试解析已配置的服务。如果找不到合适的服务,则使用默认值。

例如,当想要找到DependencyResolver时,它会首先检查IControllerFactory。如果它在那里失败,它将使用通过DependencyResolver配置的DefaultControllerFactory。由于这种先检查方法,最好返回null,然后让容器特定的异常冒泡。

这意味着此时必须捕获/吞下任何异常,因为MVC框架不负责为您处理它(onus应该在容器/ ControllerBuilder.SetControllerFactory(...)本身上)。

你可以在这个阶段记录这个,但MVC3的做法是在这些实例中返回null。

答案 1 :(得分:0)

这显然不是最佳实践,但ASP.NET MVC的实现方式是,当IoC无法解析服务时,它应返回null,以便mvc框架可以回退到其默认值。请注意,控制器/视图工厂以外的服务数量取决于它,因此抛出异常将使这些服务失效。

我在内部asp.net邮件列表中与设计决策进行了争论,但目前的情况如下: - (。

答案 2 :(得分:0)

对于IControllerFactory,您可以

.RegisterType<IControllerFactory, DefaultControllerFactory>()

我不确定哪些类实现了IViewPageActivator和ModelMetadataProvider。事件虽然可以吞下异常,但是压制异常并不是一个好习惯,因为通常异常会影响性能。一旦发生异常,框架就会填充堆栈跟踪,这需要花费时间。