ASP.NET MVC中的服务定位器替代方案

时间:2013-01-03 20:20:58

标签: asp.net-mvc design-patterns dependency-injection service-locator

阅读Mark Seemann's blog post以及引用它的this response后,我理解使用服务定位器模式通过类构造函数进行依赖注入的缺点。我还阅读了Dependency Injection with Ninject, MVC 3 and using the Service Locator Pattern,它也讨论了这个问题。

但是,我的问题涉及这个特例:

public class MyController
{
    public void GetData()
    {
        using (var repository = new Repository())
        {
            // Use the repository which disposes of an Entity Framework
            // data context at the end of its life.
        }
    }

    // Lots of other methods.
}

这里我有一个控制器,它包含一个调用存储库的方法,该存储库自动实例化一个内部的Entity Framework数据上下文。使用此单个数据上下文,因为上下文由存储库中的每个方法调用,因此在存储库对象的整个生命周期内共享单个上下文似乎是有意义的。

现在,由于控制器类很大,因此不会使用此给定存储库的可能性更大。正如我假设(可能不正确)这个实例化DC是一项昂贵的操作,我宁愿避免这样做。使用服务定位器模式允许我推迟实例化直到实际需要上下文,但是在上面的链接中给出了对它的有效参数,我宁愿避免它。

所以我想知道的是,在上述情况下是否有更有效的方法使用依赖注入,这将阻止我不必要地实例化我的存储库和底层数据上下文。

1 个答案:

答案 0 :(得分:2)

我认为答案取决于您的存储库如何管理连接。如果它在构造时打开了与数据库的连接,那么我认为问题在于您的存储库,而不是依赖注入。您的存储库只应在发出请求时打开连接,并在收到响应后立即关闭它。遵循这种模式,依赖注入仍然有意义。


根据您的更新,您最好还是使用DI,因为EF在构造时不会打开与数据库的连接,只有在发出请求时才会这样做。您的数据上下文足够小,值得为每个请求创建上下文所需的少量开销。


还有一条评论:您还应该考虑将数据上下文注入您的存储库,并让您的DI容器控制上下文的生命周期。这允许您在单个请求期间在一个或多个存储库中使用相同的上下文。 Here's a pretty good resource explaining how to implement the Repository and Unit of Work patterns with Entity Framework in ASP.NET MVC