Unity Application Block (Unity) is a lightweight, scalable dependency injection container developed by the Microsoft patterns & Practices Team. It helps build loosely coupled systems. It supports constructor injection, property/setter injection, and method call injection ). The patterns & Practices Team released the first official version of Unity (Unity 1.0) the other day (April 4 ).
Preparations
First look at some interfaces and classes, which will be used below:
Public interface iPlayer
{
Void play ();
}
Public class mp3player: iPlayer
{
Public void play ()
{
Console. writeline ("playing MP3 ");
}
}
Public class cdplayer: iPlayer
{
Public void play ()
{
Console. writeline ("playing CD ");
}
}
Public class dvdplayer: iPlayer
{
Public void play ()
{
Console. writeline ("playing DVD ");
}
}
Start with a simple example
// Create a unity container
Iunitycontainer Container = new unitycontainer ();
// Register the type ing
Container. registertype <iPlayer, mp3player> ();
// Obtain the object instance. Since the iPlayer interface has been mapped to the mp3player class in the container in the previous step,
// The mp3player class will be automatically loaded here to create an instance of this class
IPlayer player = container. Resolve <iPlayer> ();
// Call the instance method
Player. Play ();
Output:
Register Mappings
In unity, you can register mappings for iner in two ways:
1. registertype:
Register "interface" (including interface and base class) in the container to map "Specific Class. When necessary (in the preceding example, container. Resolve <iPlayer> (), the container creates instances of specific classes mapped to the specified interface.
For example: // register iplay interface ing to mp3player class
Container. registertype <iPlayer, mp3player> ();
// Register the baseplay base class mapped to the mp3player class
Container. registertype <baseplayer, mp3player> ();
An interface may map multiple specific classes. You can specify a name for each ing, for example:
Container. registertype <iPlayer, mp3player> ("mymp3player1 ");
Registertype has the following overload methods:
Registertype <Tfrom,Bytes> ()
Registertype <Tfrom,Bytes> (LifetimemanagerLifetime)
Registertype <Tfrom,Bytes> (StringName)
Registertype <Tfrom,Bytes> (StringName, LifetimemanagerLifetime)
Registertype <T> (LifetimemanagerLifetime)
Registertype <T> (StringName, LifetimemanagerLifetime)
Registertype (TypeFrom, TypeTo)
Registertype (TypeFrom, TypeTo, StringName)
Registertype (TypeFrom, TypeTo, LifetimemanagerLifetime)
Registertype (TypeFrom, TypeTo, StringName, LifetimemanagerLifetime)
Registertype (TypeT, LifetimemanagerLifetime)
Registertype (TypeT, StringName, LifetimemanagerLifetime)
For details about lifttimemanager, refer to the following article:
Unity Application Block 1.0 series (7): lifetime managers
2. registerinstance:
Register "interface" (including interface and base class) to "instance" ing in the container.
Mp3player mp3player = new mp3player ();
// Register the iPlayer interface to map to the mp3player instance
Container. registerinstance <iPlayer> (mp3player );
You can also specify a name for the ing, for example:
Container. registerinstance <iPlayer> ("mymp3player", mp3player );
Registerinstance has the following overload methods:
Registerinstance <Tinterface> (TinterfaceInstance)
Registerinstance <Tinterface> (TinterfaceInstance, LifetimemanagerLifetime)
Registerinstance <Tinterface> (StringName, TinterfaceInstance)
Registerinstance <Tinterface> (StringName, TinterfaceInstance, LifetimemanagerLifetime)
Registerinstance (TypeT, ObjectInstance)
Registerinstance (TypeT, ObjectInstance, LifetimemanagerLifetime)
Registerinstance (TypeT, StringName, ObjectInstance)
Registerinstance (TypeT, StringName, ObjectInstance, LifetimemanagerLifetime)
Get object instance
Get the object instance of the ing Class through the Resolve Method in unity.
Go back to the example at the beginning of this article and look at this line of code:
IPlayer player = container. Resolve <iPlayer> ();
The resolve method is used to obtain the mp3player instance mapped to the iPlayer interface.
Continue with the following code:
Iunitycontainer Container = new unitycontainer ();
Container. registertype <iPlayer, mp3player> ();
Container. registertype <iPlayer, cdplayer> ();
IPlayer player = container. Resolve <iPlayer> ();
Player. Play ();
The iPlayer interface registers two ing classes: mp3player and cdplayer. Is the Player Object obtained through the Resolve Method mp3player or cdplayer instance?
Check the running result:
In unity, when an interface is mapped to multiple specific classes, resolve uses the last registered ing.
Therefore, the output result "playing CD" is not surprising.
Let's look at another example:
Iunitycontainer Container = new unitycontainer ();
Container. registertype <iPlayer, mp3player> ();
// Set name to "mycdplayer" at registration"
Container. registertype <iPlayer, cdplayer> ("mycdplayer ");
IPlayer player1 = container. Resolve <iPlayer> ("mycdplayer ");
IPlayer player2 = container. Resolve <iPlayer> ();
Player1.play ();
Player2.play ();
At this time, player1 and player2 each represent which type of instance?
Check the output result:
We can see that the resolve method can obtain the specified object instance by specifying the name (the name value corresponds to the name value specified when registertype. Therefore, when an interface is mapped to multiple specific classes, it is necessary to specify names for these mappings.
Note: The name value is case sensitive.
The player2 object above uses the default ing relationship (if name is not specified in registertype or registerinstance, this ing is the default ing of this interface, if there are multiple such default mappings, follow the rule and use the last one ).
Let's look at another example:
Iunitycontainer Container = new unitycontainer ();
Container. registertype <iPlayer, mp3player> ("mycdplayer ");
Container. registertype <iPlayer, cdplayer> ("mycdplayer ");
IPlayer player = container. Resolve <iPlayer> ("mycdplayer ");
Player. Play ();
Output:
We can see that this meets the principle just mentioned:
"In unity, when an interface is mapped to multiple specific classes, resolve uses the last registered ing"
Let's take a look at the resolve overload method:
Resolve <T> ()
Resolve <T> (StringName)
Resolve (TypeT)
Resolve (TypeT,StringName)
Get all object instances
You can use the resolveall method to obtain all object instances of the specified interface:
Iunitycontainer Container = new unitycontainer ();
Container. registertype <iPlayer, mp3player> ("mymp3player ");
Container. registertype <iPlayer, cdplayer> ("mycdplayer ");
Container. registertype <iPlayer, dvdplayer> ();
Ienumerable <iPlayer> players = container. resolveall <iPlayer> ();
Foreach (iPlayer player in players)
{
Player. Play ();
}
Output result:
In this example, three specific classes are mapped for the iPlayer interface. However, the output result shows that only the output CD and MP3, that is, the players object contains only the instances of cdplayer and mp3player, why is this happening?
In Untiy, The resolveall method only returns instances of all classes with the specified name when the ing is registered.
Therefore, it is difficult to see that although three specific classes are mapped for the iPlayer interface in the above example, the resolveall method cannot be used to obtain the instance because the registertype <iPlayer, dvdplayer> () does not specify the name.
Resolveall has the following two overload methods:
Resolveall <T> ()
Resolveall (TypeT)
By: inrie (Hong Xiaojun)
Source: http://www.cnblogs.com/inrie