Reputation: 3190
I am trying to utilize dependency injection technique in an application but getting confused if this context require DI or not..
Consider an interface:
public class ICardsHub {
public T GetPlayersList<T>();
}
and its implementation:
public class GenericHub : ICardsHub {
LANPlayers LANPlayers;
WaNPlayers WANPlayers;
bool AlgorithmsUseTildainLambdas=false;
public GenericHub(LANPlayers _LANPlayers, WaNPlayers _WANPlayers,
bool algorithmsUseTildainLambdas=false) {
LANPlayers = _LANPlayers;
WANPlayers = _WANPlayers;
AlgorithmsUseTildainLambdas = algorithmsUseTildainLambdas;
}
public T GetPlayersList<T>() {
....
}
}
and the driver class is supposed to do something like:
ICardsHub _ifCards = new GenericHub(_LANPlayers, _WANPlayers);
listOfPlayers = _ifCards.GetPlayersList<List<string>>();
Now, we have two more implementations of ICardsHub
; RedHub
and BlackHub
which are instantiated later in the driver class.
Questions
Upvotes: 0
Views: 215
Reputation: 3428
In general you only use DI to help you perform unit testing. You should code against interfaces so, by using DI you can mock your components easily.
In your scenario you will have some client classes using an implementation of the ICardHub interface, the question now is, will any of those implementation perform database operations or any other external usage, if not you're most likely better of without using DI.
If you still want to use DI, go with AutoFac instead, it is IMO easy to work with.
If you have some piece of code that you think you can create a "library" off, that is a good candidate for DI. You have to think about these components as providers and DI in general is nothing new. DI just removes the responsibility of your application from creating the instances of the providers it needs, it´s the DI container doing it, and your application works with interfaces only.
Here is an Example:
Without DI
IDatabase database = new SqlServer();
With DI
IDatabase database = DIContainer.Get<IDatabase>();
As you can see, even though your application will be using the SqlServer database it knows nothing about that. Yes you have to register that type in the DI container but you do it only once, thus if you later decide to change to other implementations it is quite easy.
Upvotes: 0
Reputation: 4550
DI benefits the code for easy to maintain and easy to switch over to new implementation. I agree overloaded constructor will serve the purpose but if you have many and many dependency , still we have to make sure manually and making the code change to effectively going to each place and change it by hand and sometime you can miss some of them. having a central location will help easy to maintain. This is the reason DI is not suggested for smaller project but good sizeable projects. I do not think DI purpose to solve TDD but better maintainability and easy switching over to new implementation of classes . Example today you are using SQL SERVER as your Database , and tomorrow you change to NOSQL . One place change in class name will make sure in all the places all the code interacting with DB will work fine. TDD is one of the example
Upvotes: 2
Reputation: 9049
The primary motive of DI is testability, IMHO. So, if you look outside the testing paradigm, there might be some confusion.
In the example you've described, I see that ICardsHub defines a contract for the implementation of GenericHub, RedHub and BlackHub.
Now each of these implementation will have some logic that makes it different and thus the need for different classes to exist.
In order to test these classes (their responsibility is unique), there are some steps to be performed before these classes can perform their jobs and there might be some post these steps.
The scope of the test for this class is to ensure that Given the "pre" steps are error free, an action made by this class will have error-free output for the "post" steps to consume.
With this in mind, dependency injection allows us to
And btw, your implementation should inject Interfaces rather than concrete type. Something like -
ILANPlayers LANPlayers;
IWaNPlayers WANPlayers;
bool AlgorithmsUseTildainLambdas=false;
public GenericHub(ILANPlayers _LANPlayers, IWaNPlayers _WANPlayers,
bool algorithmsUseTildainLambdas=false) {
LANPlayers = _LANPlayers;
WANPlayers = _WANPlayers;
AlgorithmsUseTildainLambdas = algorithmsUseTildainLambdas;
}
So that in a test you can mock ILanPlayers
and IWanPlayers
which are essentially mock implementation of these types.
Upvotes: 1