2

Having read Mark Seemann's blog post along with this response which references it, I understand the disadvantages of using the Service Locator pattern over dependency injection via a class constructor. I also read this Dependency Injection with Ninject, MVC 3 and using the Service Locator Pattern which discusses the issue as well.

However, my question concerns this particular case:

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.
}

Here I have a controller which contains a method that calls a repository which automatically instantiates an internal Entity Framework data context. This single data context is used, because the context is called by every method in the repository so it seems to make sense to share a single context for the entire lifetime of the repository object.

Now, as the controller class is large, there is a greater chance than not that this given repository will not be used. As I assume (perhaps incorrectly) that this instantiating a DC is an expensive operation, I would prefer to avoid doing so. Using the service locator pattern allows me to defer instantiation until the context is actually needed, but given the valid arguments against it in the above links, I would prefer to avoid it.

So what I would like to know is if there is a more efficient way of using dependency injection in the above case that would prevent me from instantiating my repository and underlying data context unnecessarily.

Community
  • 1
  • 1
Levi Botelho
  • 24,626
  • 5
  • 61
  • 96

3 Answers3

2

I think the answer depends on how your repository manages connections. If it opens a connection to the database when constructed, then I think the problem is with your repository, not Dependency Injection. Your repository should only open a connection when a request is made and close it as soon as a response is received. Following this pattern, Dependency Injection still makes sense.


Based on your update, you're still better off using DI because EF doesn't open a connection to the database when constructed, only when a request is made. Your data context is small enough that it's worth the small amount of overhead needed to create the context per request.


One more comment: you should also consider injecting your data context into your repositories and letting your DI container control the lifetime of the context. This allows you to use the same context in one or more repositories during a single request. Here's a pretty good resource explaining how to implement the Repository and Unit of Work patterns with Entity Framework in ASP.NET MVC.

sellmeadog
  • 7,437
  • 1
  • 31
  • 45
  • I had considered this when writing my repository, however as every single method in the repository makes use of the same connection it is convenient to tie the life of the connection to the life of the repository instance. Is there a good reason not to do this? – Levi Botelho Jan 03 '13 at 20:33
  • If your controller is being used in ASP.NET MVC then every method won't make use of the same connection because every request will instantiate a new controller, thus a new repository and thus a new connection. – sellmeadog Jan 03 '13 at 20:36
  • I updated the question with more information in response to your comment. – Levi Botelho Jan 03 '13 at 20:49
  • Thanks for the update. Good reasoning on the context creation. – Levi Botelho Jan 03 '13 at 20:56
  • Updated my answer with a good resource about using EF with the Repository and Unit of Work patterns. – sellmeadog Jan 03 '13 at 21:06
2

As the controller class is large, there is a greater chance than not that the connection will not be used on any given construction, so it doesn't make sense to instantiate the repository and open a connection using standard constructor-based DI.

Inject a Lazy, a Func, or a factory instead:

public class MyController
{
    // Use constructor injection to populate this.
    private Func<MyRepository> _repository;

    public void GetData()
    {
        using (var repository = _repository())
        {
            // ...
        }
    }
}

That way you can avoid creating actual instances until you need them.

@sellmeadog's answer is good too.

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
2

You're asking whether or not you should inject a database connection into the Repository constructor? You could try using the Abstract Factory design pattern injecting a database connection factory instead of an actual database connection.

public class MyController
{
    public void GetData()
    {
        using (var repository = new Repository(IDatabaseConnectionFactory dbConnFac))
        {
            // Use the repository which disposes of a database connection
            // at the end of its life.
        }
    }

    // Lots of other methods.
}

This way you get the benefits of dependency injection while still allowing the Repository to manage the life cycle of its database connections.

Raymond Saltrelli
  • 4,071
  • 2
  • 33
  • 52