Annie
Annie

Reputation: 3190

Improvising using IoC - Unity

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

  1. How can the Unity IoC/DI benefit this scenario?
  2. If striping out method parameters from the interface and injecting them to overload constructor solves the problem, then what is the suitable scenario for DI container usage?

Upvotes: 0

Views: 215

Answers (3)

MeTitus
MeTitus

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

Devesh
Devesh

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

Srikanth Venugopalan
Srikanth Venugopalan

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

  1. easily assume the preconditions (i.e. inject mock objects, with the assumptions setup)
  2. perform an action (responsibility of this class)
  3. Verify the output.

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

Related Questions