Reputation: 348
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
Upvotes: 8
Views: 7480
Reputation: 7681
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.
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.
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.
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
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
Reputation: 2258
Answers to your questions:
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