Geeks With Blogs

News
Daniel Garcia Let's code something up!

After a little introduction to Inversion of Control and Dependency Injection, we'll see how DI containers behave in a real-world application. To do so, we'll talk about Unity, developed by Microsoft and belonging to the Enterprise Library package.

Therefore, Unity is a Dependency Injection Framework or DI Container. It can be downloaded from Codeplex or using NuGet from inside of Visual Studio. We'll use this last method in our example.

Let's begin creating a new Console Project which will be called, such as UnityExample.

Then, we'll make use of NuGet to add a reference to Unity. It'll be so simple as performing right-click over project references and selecting the Manage NuGet Packages... option.

Then, we'll select the Online option in the right side tree and we'll write Unity> in the search box to get the package. Once found, we'll click on the Install button.

Creating the sample classes

Let's code a similar example to the previous article. In this case, instead using engines and vehicles, let's imagine a play centre with tables, each one allows to play to a board game. The Table class will be in charge of the table modelling, while the IGame interface will typify the common behavior to every game: add players, remove players and show the present status of the game.

We'll create a couple of games which will implement the interface:TrivialPursuit and TicTacToe

First of all, we code the interface.

1
2
3
4
5
6
7
8
9
10
11
12
public interface IGame
{
    string Name { get; }
    int CurrentPlayers { get; }
    int MinPlayers { get; }
    int MaxPlayers { get; }
 
    void addPlayer();
    void removePlayer();
    void play();
    string result();
}

Next, we code a class for Trivial Pursuit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class TrivialPursuit : IGame
{
    private string _status;
 
    public TrivialPursuit()
    {
        Name = "Trivial Pursuit";
        CurrentPlayers = 0;
        MinPlayers = 2;
        MaxPlayers = 8;
        _status = "No active games";
    }
 
    #region IGame Members
 
    public string Name { get; set; }
     
    public int CurrentPlayers { get; set; }
 
    public int MinPlayers { get; set; }
 
    public int MaxPlayers { get; set;  }
     
    public void addPlayer()
    {
        CurrentPlayers++;
    }
 
    public void removePlayer()
    {
        CurrentPlayers--;
    }
 
    public void play()
    {
        if ((CurrentPlayers > MaxPlayers) || (CurrentPlayers < MinPlayers))
            _status = string.Format("{0}: It's not possible to play with {1} players.", Name, CurrentPlayers);
        else
            _status = string.Format("{0}: Playing with {1} players.", Name, CurrentPlayers);
    }
 
    public string result()
    {
        return _status;
    }
 
    #endregion
}

...and another one for the Tic Tac Toe.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class TicTacToe : IGame
{
    private string _status;
 
    public TicTacToe()
    {
        Name = "Tic Tac Toe";
        CurrentPlayers = 0;
        MinPlayers = 2;
        MaxPlayers = 2;
        _status = "No active games";
    }
 
    #region IGame Members
 
    public string Name { get; set; }
 
    public int CurrentPlayers { get; set; }
 
    public int MinPlayers { get; set; }
 
    public int MaxPlayers { get; set; }
 
    public void addPlayer()
    {
        CurrentPlayers++;
    }
 
    public void removePlayer()
    {
        CurrentPlayers--;
    }
 
    public void play()
    {
        if ((CurrentPlayers > MaxPlayers) || (CurrentPlayers < MinPlayers))
            _status = string.Format("{0}: It's not possible to play with {1} players.", Name, CurrentPlayers);
        else
            _status = string.Format("{0}: Playing with {1} players.", Name, CurrentPlayers);
    }
 
    public string result()
    {
        return _status;
    }
 
    #endregion
}

At last, we code the Table class which will contain an IGame interface, which will be injected through its constructor.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Table
{
    private IGame game;
 
    public Table(IGame game)
    {
        this.game = game;
    }
 
    public string GameStatus()
    {
        return game.result();
    }
 
    public void AddPlayer()
    {
        game.addPlayer();
    }
 
    public void RemovePlayer()
    {
        game.removePlayer();
    }
 
    public void Play()
    {
        game.play();
    }
}

Type registration

The first thing we must to do will be instanciating a Unity Container and registering the type we want it to resolve for us. As a first example, we'll register the IGame interface with the TrivialPursuit class. This will mean that, when we resolve the dependencies, Unity will instantiate an object from the TrivialPursuit class when we resolve any object containing (or being) a dependency of IGame type.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Table
{
    private IGame game;
 
    public Table(IGame game)
    {
        this.game = game;
    }
 
    public string GameStatus()
    {
        return game.result();
    }
 
    public void AddPlayer()
    {
        game.addPlayer();
    }
 
    public void RemovePlayer()
    {
        game.removePlayer();
    }
 
    public void Play()
    {
        game.play();
    }
}

Type resolution

Therefore, each time we'll ask Unity to resolve an IGame interface, the framework will check if the IGame interface is registered, and, in possitive match, it will provide an instance of the mapped class (in this case, TrivialPursuit):

1
2
3
4
5
6
7
8
9
// Make Unity resolve the interface, providing an instance
// of TrivialPursuit class
var game = unityContainer.Resolve<IGame>();
 
// Check that behavior is correct
game.addPlayer();
game.addPlayer();
Console.WriteLine(string.Format("{0} personas están jugando a {1}", game.CurrentPlayers, game.Name));
Console.ReadLine();

Running this code will show the following (and expected) result:

Unity is also able to resolve types indirectly. On the previous example, we saw that IGame is registered to inject a TrivialPursuit instance. Remember that our table (instance from Table class) got a reference to an IGame interface, which was injected through its constructor.

1
2
3
4
5
6
7
8
public class Table
{
    private IGame game;
 
    public Table(IGame game)
    {
        this.game = game;
    }

If we ask Unity to resolve an instance of Table class, we'll realize that all those public dependencies present on the class and registered by Unity are going to be injected, that is to say, it will provide us a Table instance injecting an object of TrivialPursuit class in the moment when it finds an IGame interface:

1
2
// Instance a Table class object through Unity
var table = unityContainer.Resolve<Table>();

The Table constructor gets a reference to IGame interface as parameter. Therefore, Unity will search inside its registry list and will concloude that it must to inject a new instance (new TrivialPursuit()) instead the interface itself. Let's add the following code to check if everything is working as expected:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
static void Main(string[] args)
{
    // Declare a Unity Container
    var unityContainer = new UnityContainer();
 
    // Register IGame so when dependecy is detected
    // it provides a TrivialPursuit instance
    unityContainer.RegisterType<IGame, TrivialPursuit>();
     
    // Instance a Table class object through Unity
    var table = unityContainer.Resolve<Table>();
 
    table.AddPlayer();
    table.AddPlayer();
    table.Play();
 
    Console.WriteLine(table.GameStatus());
 
    Console.ReadLine();
}

If we run the program, we'll see that the result is correct:

Property injection

Besides we've seen so far, Unity allows us to perform other operations, such as assigning values ??to properties when performing type resolution.

1
2
3
// Inject a property when dependency is resolved
InjectionProperty injectionProperty = new InjectionProperty("Name", "Trivial Pursuit Genus Edition");
unityContainer.RegisterType<IGame, TrivialPursuit>(injectionProperty);

When IGame is resolved, we get an TrivialPursuit instance, but its Name Property is now set to the value Trivial Pursuit Genus Edition. If we do the following to replace the previous ones, we'll see that the result is correct:

Parameter injection

Another possibility that we have when we inject a dependency is making the injection just in the moment we are resolving it. Until now we've seen the case where the default instanced game is TrivialPursuit. However, there may be cases where we want IGame to be assigned to another game. We can ask Unity to provide us an instance of TicTacToe just injecting the constructor parameters when the dependency is resolved.

So, Table class exposes a constructor with an IGame parameter called game:

1
2
3
4
public Table(IGame game)
{
    this.game = game;
}

If we don't indicate it explicitely, Unity will resolve the game parameter automatically, performing a search in the registered dependencies (in this case, it corresponds with TrivialPursuit). However, it's possible to say to the container to resolve the dependency explicitely, ignoring the default behavior:

1
2
3
4
5
6
7
8
9
// Override the constructor parameter of Table class
var table2 = unityContainer.Resolve<Table>(new ParameterOverride("game", new TicTacToe()));
 
table2.AddPlayer();
table2.AddPlayer();
table2.Play();
 
Console.WriteLine(table2.GameStatus());
Console.ReadLine();

The result will be the following:

You can download the example code from here.

You can find the Spanish version of this article here.

Posted on Thursday, January 23, 2014 4:49 PM .net , example , c# , IoC , inversion of control , DI , Dependency Injection , unity | Back to top


Comments on this post: Introduction to Dependency Injection with Unity

# re: Introduction to Dependency Injection with Unity
Requesting Gravatar...
Hi, Good work
Left by Asif Iqbal on Jun 16, 2014 8:55 AM

# re: Introduction to Dependency Injection with Unity
Requesting Gravatar...
Under "Type registration" the following code snippet does not illustrate the type registration. There is no instantiation of a unity container, and the registration is missing.
Left by Nick Birke on Sep 16, 2014 5:20 PM

# re: Introduction to Dependency Injection with Unity
Requesting Gravatar...
Awesome example.
Left by Qamar Ali on Sep 25, 2014 5:51 AM

# re: Introduction to Dependency Injection with Unity
Requesting Gravatar...
I am wondering if Unity has the similar methods for WhenTargetHas and When.

For example in ninject we can do:
kernel.Bind<ILogManager>().To<TransactionalLogManager>().WhenTargetHas<TransactionalAttribute>().InRequestScope();

and

kernel.Bind<IElementOfWork>().To<MediaElementOfWork>().When(request =>request.Target != null && request.Target.Member.DeclaringType != null && request.Target.Member.DeclaringType.Assembly == typeof(MvcApplication).Assembly && request.Target.Member.DeclaringType != typeof(MembershipErrorController)).InRequestScope();

How can we translate the ninject codes above to unity?
Left by Fufusitaus on Jan 12, 2015 3:25 AM

# re: Introduction to Dependency Injection with Unity
Requesting Gravatar...
As Nick already pointed out, the code under "Type registration" is missing. However in the link spanish version of the articel to code is actually there:

static void Main(string[] args)
{
// Declaramos un contenedor Unity
var unityContainer = new UnityContainer();

// Registramos IGame para que cuando se detecte la dependencia
// proporcione una instancia de TrivialPursuit
unityContainer.RegisterType<IGame, TrivialPursuit>();
}
Left by Ronald Rink on May 21, 2015 4:23 AM

# re: Introduction to Dependency Injection with Unity
Requesting Gravatar...
Better than the bible about it that microsoft has written.

Thank you
Left by Sandeep on Sep 18, 2015 8:04 PM

# re: Introduction to Dependency Injection with Unity
Requesting Gravatar...
Best Unity tutorial so far. Very good real life example taken that helped me understand the purpose.
Left by Radkan on Oct 27, 2016 10:35 PM

# re: Introduction to Dependency Injection with Unity
Requesting Gravatar...
Very helpful, thanks!
Left by Ryan on Mar 21, 2017 3:16 PM

Your comment:
 (will show your gravatar)


Copyright © Daniel Garcia | Powered by: GeeksWithBlogs.net