给定这个MVC控制器的示例;伪代码...
PostController
{
private IGetPost _getPost;
private ICreatePost _createPost;
private IDeletePost _deletePost;
private IUpdatePost _updatePost;
public ActionResult Get()
{
return _getPost();
}
public ActionResult Create(post)
{
return _createPost(post);
}
public ActionResult Update(posts)
{
return _updatePost(post);
}
public ActionResult Delete(post)
{
return _deletePost(post);
}
}
我的问题是,如果调用了控制器上的任何动作,则控制器的所有依赖项都会为它们创建实例,这似乎是性能的嗡嗡声。有一个更好的方法吗?我唯一的想法是创建4个不同的控制器,每个控制器仅需执行一个操作,但这似乎有点过头了。我还考虑过在每个操作中直接调用DependencyResolver,但是我不确定如果这样做会对单元可测试性产生什么影响。
最佳答案
为什么它是性能嗡嗡声?您是否测量过这种情况?虽然确定哪些实现映射到什么接口会产生开销,但大多数值得其使用的dependency injection(DI)容器都会进行一次此映射(并且通常会在运行中动态创建编译后的代码,以便尽可能快地进行查找)来创建映射。映射。
然后只需要创建对象即可,这与使用new
keyword没什么不同。
对于一般情况,这不会对性能造成影响。考虑到这是一个Web应用程序,如果您获得了Stack Overflow级别的流量,那么它很可能成为扩展的障碍。这些操作中的每一个都是廉价的,但是如果乘以数百万,则总计非常昂贵,通常,这些是可能导致资源争用的事物类型,等等。
假设情况并非如此(流量的堆栈溢出级别),那么您很可能会遇到性能问题的地方是构造函数的实现。
如果这四个接口(或任意数量的接口)的实现成本很高,那不是DI的功能,而是代码的功能,那您将从优化中获得更多好处。
调整依赖项注入可能唯一有益的地方是,如果其中一个或多个实现的构建具有高开销,并且您让DI容器为所有接口实现创建了一个实例,而不是为每个接口实现创建了一个实例。但是,仅当您确定该选项可用时,才应通过DI层研究生命周期管理(这意味着让该类的一个实例满足所有请求是可行的;它是线程安全的吗?很长一段时间的任何资源?等)
如果您真的对此感到担心,并且上述方法不适用或不是一种选择,那么可以,您可以创建许多较小的控制器,这可能由于其他原因而有意义;如果您正在执行的动作在逻辑上彼此不相关,则它们可能应该位于单独的控制器中。
但是,看一下您所采取的行动,看来您所采取的逻辑鸿沟是正确的。
长话短说,不要在未将其视为重要因素的地方尝试优化性能。
也就是说,无论您做什么,都不会解析类内部的依赖关系。如果这样做,您将失去DI的所有好处,并且将您的类与DI容器紧密绑定(并可能破坏它的可测试性)。
关于asp.net-mvc - MVC DI/IoC是否有太多依赖项?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14156941/