【发布时间】:2013-03-23 14:07:15
【问题描述】:
我不确定是不是只有我一个人,但我感觉 ASP.NET MVC 控制器中使用的构造函数注入会导致不必要的资源消耗。
在创建控制器时仍需要创建未用于特定网络请求的组件。 这就像在我渴了牛奶的时候买了牛奶和果汁,然后我就把果汁扔掉了。
比较控制器的构造函数注入和服务定位器的这些示例,以澄清我的担忧。
Constructor Injection,创建了booth deps但只使用了一个。
public class MyController : Controller
{
private readonly IDep1 _dep1;
private readonly IDep2 _dep2;
public MyController(IDep1 dep1, IDep2 dep2)
{
_dep1 = dep1;
_dep2 = dep2;
}
public ActionResult Index()
{
_dep1.MakeStuff();
return View();
}
public ActionResult PageTwo()
{
_dep2.MakeStuff();
return View();
}
}
Service Locator,每个dep只有在使用时才会创建。
public class MyController : Controller
{
public ActionResult Index()
{
var dep1 = ServiceLocator.Resolve<IDep1>();
dep1.MakeStuff();
return View();
}
public ActionResult PageTwo()
{
var dep2 = ServiceLocator.Resolve<IDep2>();
dep2.MakeStuff();
return View();
}
}
请注意 IoC 容器(由于许多原因是有益的)仍然可以用于服务定位器模式。我不希望这是围绕 IoC 和容器框架的讨论,也不是构造函数注入的其他好处(依赖关系的清晰可见性等)。我关心的是构造函数注入模式以及它在 ASP.NET MVC 控制器情况下如何浪费资源。
我想这里的主要问题是: 对于上述场景(ASP.NET MVC 控制器)而言,Service Locator 是更好的解决方案性能吗?
【问题讨论】:
-
在大多数(如果不是所有)IoC 容器中,接口类型和具体类型都被存储,并且只有在检测到依赖关系时才会真正创建类型,例如对类型具有依赖关系的构造函数。
-
没错,所以在第一个示例中,展位依赖项是由 IoC 容器创建的,并且只使用了一个,对吧?
-
我想说,在这种情况下,可测试性远远超过了性能提升,正如@motime 所说,如果您的瓶颈在于创建依赖项(并且他们没有进行基于 I/O 的操作)或其他繁重的工作)。你在一个好地方。
-
你在构造函数中到底在做什么?根据 .NET Framework 设计指南: 在构造函数中做最少的工作。除了捕获构造函数参数之外,构造函数不应该做太多工作。任何其他处理的成本应延迟到需要时。如果您这样做,那么您不必担心资源消耗。
-
我不是在谈论我的具体问题。这是关于设计和后果的一般问题。假设一个控制器有几个方法,每个方法使用 4 个不同的域服务实例 => 16 个对象,其中只有 4 个用于特定请求(操作方法)=> 12 个不必要的实例。这 12 个对象本身可能有一个图表,比如另外两个级别和每个级别上的 3 个实例 => 12 个 => 108 个实例创建中的每一个都额外增加 9 个,这是不必要的。在某些情况下(短时间内大量 Web 请求)会影响性能/利用率。没有?
标签: asp.net-mvc dependency-injection service-locator