Like other application blocks in the Enterprise Library, you can specify the actions of Unity through configuration.
The Unity application block can read configuration information from the XML configuration file. The configuration file can be App. config of the Windows Forms Application or Web. config of the ASP. NET application. Of course, you can also load configuration information from any other XML format file or other data sources.
In this article, we will learn the format, configuration reading, and instance acquisition of the Unity configuration file.
1. Unity configuration file format
The Unity configuration file looks like the following:
<? Xml version = "1.0" encoding = "UTF-8"?>
<Configuration>
<ConfigSections>
<Section name = "unity" type = "Microsoft. Practices. Unity. Configuration. UnityConfigurationSection, Microsoft. Practices. Unity. Configuration"/>
</ConfigSections>
<Unity>
<Containers>
<Container name = "containerOne">
<Types>
<Type = "System. Data. IDbConnection, System. Data"
MapTo = "DorianDeng. UnityConfigurationExe. MyDefaultConnection, DorianDeng. UnityConfigurationExe"/>
<Type name = "baseMap" type = "System. Data. Common. DbConnection, System. Data"
MapTo = "DorianDeng. UnityConfigurationExe. MyDbConnection, DorianDeng. UnityConfigurationExe" lifetime = "Transient"/>
<Type name = "interfaceSingleton" type = "System. Data. IDbConnection, System. Data"
MapTo = "DorianDeng. UnityConfigurationExe. MyDbConnection, DorianDeng. UnityConfigurationExe" lifetime = "Singleton"/>
</Types>
<Instances>
<Add name = "MyInstance1" type = "System. String" value = "Some value"/>
<Add name = "MyInstance2" type = "System. DateTime" value = "2008-02-05T17: 50: 00"/>
</Instances>
<Extensions>
<! -- <Add type = "MyApp. MyExtensions. SpecialOne"/> -->
</Extensions>
</Container>
</Containers>
</Unity>
</Configuration>
1.1 configuration section
The Configuration section of Unity is named "unity". The type of the section handler is Microsoft. Practices. Unity. Configuration. UnityConfigurationSection, which is included in the Assembly Microsoft. Practices. Unity. Configuration.
1.2 child elements of unity
The child element of unity contains a containers element, which has a required property Default (this property is unavailable in the current version ), it is used to specify the default container when no container is specified to obtain the container configuration.
The containers element can contain several iner elements. The container element is the configuration of each container. It has an optional name attribute to specify the container name.
The container element has the following sub-elements:
- Types Element
- Instances Element
- Extensions Element
Note: containers cannot be nested, that is, the iner element cannot be nested.
1.3 types Element
The types element is one of the Child elements of the iner element. Contains any number of type elements to add type registration.
The following table lists the attributes of the type element used for types.
Attribute |
Description |
Name |
The name used when registering this type. This attribute is optional. If this attribute is not specified, the add element is the default type ing. |
Type |
The source type configured in the container. If this is ing registration, this is the type of the starting object of the ing; if this is a single-piece registration, this is the type of the object. This attribute is required. |
MapTo |
The target type of the type ing. If this is ing registration, this is the type of the mapped target object. This attribute is optional. |
Lifetime |
Set the lifecycle of a given type and name. Is a value from the LifetimeStyle enumeration. The valid value is Transient (default), which causes the container to create a new instance each time; and Singleton, which causes the container to return the same instance for each request. If both the type and mapto attributes are specified when a single piece is configured, The SetSingleton method returns the type specified in the mapTo attribute. If no value is specified for the mapTo attribute, the SetSingleton method returns the type specified in the type attribute. |
Singleton is a single piece in a single-piece pattern. The SetSingleton method is a method provided by the container to obtain a single piece. The container determines how the instance is generated based on the lifetime attribute.
1.4Instances sub-element
The instances element maintains the list of existing object instances used for this container. These objects (including simple types such as database connection strings) are registered using the RegisterInstance method of the container. The instances element contains a series of add elements for adding a single instance.
The following table lists the attributes of the add element used for an instance.
Attribute |
Description |
Name |
The name used to register this instance. This attribute is optional. |
Type |
The type of the instance. This attribute is optional. If this parameter is ignored, it is assumed that the type is System. String. |
Value |
Value used to initialize the instance. This attribute is required. |
TypeConverter |
Type converter used to convert the provided value to the matching type of the instance. If not specified, the default converter of the specified type is used. This attribute is optional. |
1.5Extensions Element
The extensions element maintains the list of extensions added to the Unity container. Extensions contains a series of add elements for adding a single extension.
The following table lists the attributes of the add element for extension.
Attribute |
Description |
Type |
The extended type added to the container. This attribute is required. |
2 Examples
Now, we only learn the types sub-elements and instances sub-elements, and the extensions sub-elements will be separately used later.
In the example, we define two inherited from System. data. common. the MyDefaultConnection and MyDbConnection of the DbConnection class, although these two classes cannot implement real connections, this is enough as an example.
2.1 read configurations and create a container
For example, in the configuration file at the beginning of the article, we define a named window "containerOne". Therefore, we can use the following code to read the configuration and use the configuration to initialize the container.
Note: The Unity Application Block does not automatically read configuration information or create and prepare containers.
/// <Summary>
/// Create a container.
/// </Summary>
/// <Returns> </returns>
Private static IUnityContainer CreateContainer (){
IUnityContainer container = new UnityContainer ();
UnityConfigurationSection section
= (UnityConfigurationSection) ConfigurationManager. GetSection ("unity ");
Section. Containers ["containerOne"]. GetConfigCommand (). Configure (container );
Return container;
}
In the above Code, we use the first line to instantiate a container, the second line uses the. NET ConfigurationManager class to read the configuration section, and the third line initializes the container.
If we define a default container (an unnamed container), we can use the following code to initialize the container:
Section. Containers. Default. GetConfigCommand (). Configure (container );
Nested containers provide useful functions for managing dependency injection and object lifecycles, which will be discussed in detail in future articles.
Although containers cannot be nested in the configuration file, you can use code to create and initialize containers, as shown in the following code:
IUnityContainer parentContainer = new UnityContainer ();
IUnityContainer childContainer = parentContainer. CreateChildContainer ();
UnityConfigurationSection section
= (UnityConfigurationSection) ConfigurationManager. GetSection ("unity ");
Section. Containers ["containerOne"]. GetConfigCommand (). Configure (parentContainer );
Section. Containers ["nestedChildContainer"]. GetConfigCommand (). Configure (childContainer );
2.2 create a default instance
The default instance is the instance registered through the Untitled type ing, such as the first type in the sample configuration file. Then, we can use the following code to obtain and use the instance. (For the complete code, see the source file .)
Private static void DefaultMap (){
IUnityContainer container = CreateContainer ();
IDbConnection connection = container. Get <IDbConnection> ();
Connection. Open ();
Connection. Close ();
}
The execution result is as follows:
2.3 obtain Objects Based on keys and types
For the second type element in the configuration file, we can use the following statement to obtain the object:
DbConnection connection = container. Get <DbConnection> ("baseMap ");
2.4 obtain a single-piece object
For the concepts related to Singleton, you can refer to the pattern in the design mode and only discuss how to use Unity to obtain single-piece objects.
The third type in the configuration file is the configuration of a single-piece object (lifetime = "Singleton "). Through the following code, we can see whether Unity has obtained a single-piece object.
/// <Summary>
/// Obtain a single-piece object.
/// </Summary>
Private static void SingletonMap (){
IUnityContainer container = CreateContainer ();
IDbConnection connection = container. Get <IDbConnection> ("interfaceSingleton ");
Connection. ConnectionString = "server = 10.99.123.22 ,...";
Console. WriteLine (connection. ConnectionString );
IDbConnection secodeConnection = container. Get <IDbConnection> ("interfaceSingleton ");
SecodeConnection. ConnectionString = "server = 192.168.0.2 ...";
Console. WriteLine (connection. ConnectionString );
}
Shows the effect:
From this we can see that although two objects are obtained, in fact, by configuring and specifying, the Unity container manages a single-piece object for us, and the two variables actually point to the same object reference.
2.5 instances instance
The instances element in the configuration file serves to register an existing single-piece object using the RegisterSingleton method of Unity. Therefore, you can use the following code to obtain the two instances defined in the configuration file:
/// <Summary>
/// Instances element example.
/// </Summary>
Private static void InstancesExample (){
IUnityContainer container = CreateContainer ();
String instances1 = container. Get <string> ("MyInstance1 ");
Console. WriteLine (instances1 );
DateTime instances2 = container. Get <DateTime> ("MyInstance2 ");
Console. WriteLine (instances2 );
}
It can be seen that this is no different from the code obtained from the previous examples. Therefore, no matter which method is used for configuration, it is the same for the customer code.
3 conclusion
Currently, Unity is only in the CTP version, so some bugs exist in the Code and documents. Therefore, the content of the article may be different from the content of the document, but this is the correct method of use.
For the source code in the example, download it here.
For details about how to use the Unity Method, continue to pay attention to my ideals and beauty.
Hope to help you!
Deng Ming