caesardo
caesardo

Reputation: 348

static methods vs dependency injection for data access layer

For my ASP.NET MVC projects, I used to rely heavily on static methods for my data access, kind of like this :

public class MyTable
{

    public static IEnumerable<MyTable> findAll()
    {
        using (var connection = new SqlConnection(Provider.connString))
        {
            //implementation here
        }


        return datas;
    }

    public static MyTable find(guid id)
    {
        using (var connection = new SqlConnection(Provider.connString))
        {
            //implementation here
        }

    }

}

so i could call them like this in my controller :

var datas = MyTable.findAll();

I'm comfortable with it, but I doubt I'm doing a good practice for data access with it.

now, I'm trying to apply dependency injection just for some learning purpose to my data access class something like this :

public class MyTable
{

    public IDatabaseEngine _engine = null;

    public MyTable()
    {
    }

    public MyTable(IDatabaseEngine engine)
    {
        _engine = engine;
    }

    public IEnumerable<MyTable> findAll()
    {
        using (var connection = _engine.getConnection())
        {
            //implementation here
        }
        return datas;
    }

    public MyTable find(guid id)
    {
        using (var connection = _engine.getConnection())
        {
            //implementation here
        }
        return data;
    }
}

the thing is, it means that I have to create an instance of MyTable class to invoke method for data access on my controller something like this :

var table = new MyTable(new MSSQLEngine(provider.connString));
var datas = table.findAll(); 

well either I'm very inexperienced to figure this out or I'm doing it wrong, I feel uncomfortable doing instantiation of object for every data access I need.

My question is

  1. Am I doing the Dependency Injection wrong ? (I think I am)
  2. Is it good practice to create object of data access class to invoke data access method either in the controller or other classes?
  3. Is it good practice to do it using static method instead ? (Like I do in the first example)
  4. if my DI implementation is wrong, how do I make it right?

Upvotes: 8

Views: 7480

Answers (3)

George Polevoy
George Polevoy

Reputation: 7681

  1. Dependency injection is just a technique to store a dependency in an instance field, so you are basically are doing a it right in the MyTable implementation.

  2. You can benefit from Dependency Injection if you obtain an instance of IDatabaseEngine in a constructor for a controller, if you are going to mock database engine in a controller's test. You still need a way to inject the instance in your application. As for now, you are creating an instance of concrete class MSSQLEngine in controller, so there is no benefit.

  3. Using a static method is not good in this case, because at the time you decide to implement database-agnostic tests, you would need to refactor to using instances. It's a good practice to start with a minimal test setup, so you could achieve testability in an early stage of your project lifetime. I recommend to do this hard part before your codebase grows large.

  4. Learn how to inject instances of IDatabaseEngine in controllers, and write a minimum test taking benefit of dependency injection. Most MVC frameworks allow to set up an IoC container serving as a factory. In a test, you would need to use some mock implementation, or a mocking framework, such as Moq to make up instances of IDatabaseEngine.

Upvotes: 1

magallanes
magallanes

Reputation: 6854

While DI is cool for some cases but in most cases is an over engineering!.

I explain. How to creates a static method. Just put "static" in front of the method. And you could call it easily by calling the Class.Method(). Also, its efficient to the system, because the method is only created once.

Pro: is efficient. Cons: is not mutable

While DI, you may be need some container, then an interface, and you could add a class, any class that implements the interface. And, in some part of the code, you will need to create an instance of the class (ergo a new instance of the method).

Pro: is mutable Cons: is not efficient, its verbose.

Upvotes: 9

Andrei Mihalciuc
Andrei Mihalciuc

Reputation: 2258

Answers to your questions:

  1. No, see below detailed answer
  2. Main advantage of DI is dependency on abstraction not on implementation. You don't need to create instances of classes, DI will do it for your. You just need to inject interfaces into your classes and register them in your IoC.
  3. No, as you will no be able to write unit tests to your methods.
  4. See below.

To use correctly DI, first you need extract MyTable class into an interface and then inject that interface into your controller.

public interface IMyTable 
{
    IEnumerable<MyTable> findAll();
    // other methods
}

public class MyTable : IMyTable 
{
    // your implementation
}

Then your controller should look like:

public class YourController : Controller
{ 
    private IMyTable myTable;
    public YourController(IMyTable myTable)
    {
        this.myTable = myTable;
    }

    public ActionResult YourAction()
    {
        var result = myTable.findAll();
        // ...
    }
}

I personally use Castle Windsor as IoC container, here is an example of using Castle Windsor in ASP.NET MVC application

Upvotes: 4

Related Questions